Funkcja random.rand () firmy Numpy generuje losowe liczby zmiennoprzecinkowe z przedziału od 0 do 1. Jak przekształcić dane wyjściowe tej funkcji, aby uzyskać losowe liczby zmiennoprzecinkowe z przedziału od -1 do 1?

Wyjście prądowe:

In[]: numpy.random.rand(3, 2)
Out[]: 
array([[0.13568674, 0.72465483],
       [0.48726461, 0.68867378],
       [0.50463821, 0.28619853]])

Pożądane (przykładowe) wyjście:

In[]: numpy.random.rand(3, 2)
Out[]: 
array([[-0.13568674, 0.72465483],
       [-0.48726461, 0.68867378],
       [0.50463821, -0.28619853]])

Nie chciałbym używać random.uniform ().

1
Patrick 18 grudzień 2019, 12:42
4
(numpy.random.rand(3, 2) - 0.5) * 2
 – 
William Miller
18 grudzień 2019, 12:45
1
Jaki jest powód, aby nie używać np.random.uniform? To dziwne ograniczenie; czy masz dobry powód, aby tego unikać i czy istnieją inne, podobne ograniczenia? Wydaje się, że działasz pod nietypowym zestawem ograniczeń i dobrze byłoby wiedzieć, jakie to są.
 – 
Mark Dickinson
18 grudzień 2019, 14:18

2 odpowiedzi

Zasadniczo musisz skalować i przesuwać zakres (0, 1) normalnie generowany przez np.random.rand() do zakresu docelowego (-1, 1):

import numpy as np

N = 10
max_val, min_val = 1, -1
range_size = (max_val - min_val)  # 2
np.random.rand(N) * range_size + min_val

Lub inna równoważna algebra.


Alternatywnie możesz użyć np.random.randint() do wygenerowania zakresu int do podzielenia przez (ułamek) jego rozmiaru.

Dla Twojego konkretnego zakresu wyglądałoby to następująco:

import numpy as np


N = 10
L = 100
np.random.randint(-L, L, N) / L

Byłoby to (nieco) wolniejsze niż podejście np.random.random(), ale dałoby kontrolę nad „gęstością” wyniku.


(ZMIENIONO: jawnie napisz związek między algebrą a zakresem docelowym)

2
norok2 21 grudzień 2019, 11:04
Druga opcja utworzy bardziej warstwowe lub podzielone losowo próbkowanie, ponieważ obecnie istnieje tylko 200/10 = 20 możliwych wartości. Daje to kontrolę nad gęstością. Może to jednak, ale nie musi mieć zastosowania do konkretnego przypadku użycia. Najlepszą rzeczą, być może, jest zastosowanie np.random.rand, a następnie użycie jakiejś formy binningu, jeśli to konieczne. Ale tak, obie metody mogą być odpowiednimi sposobami pobierania próbek w niektórych scenariuszach. Jeśli ktoś na ślepo stosuje jednolite losowe dobór próby, sugerowałbym zastosowanie pierwszej metody.
 – 
CypherX
21 grudzień 2019, 11:24

Jeśli chcesz wygenerować losową liczbę zmiennoprzecinkową między dwiema wartościami a i b, gdzie a < b, jest to robione w następujący sposób. Jest to równoważne z redystrybucją lub ponownym przeskalowaniem losowej dystrybucji między [0,1] do żądanego przedziału [a,b] (odpowiednik rozciągania lub kompresji, w zależności od tego, czy (b - a) to <, = lub > (1 - 0).

import numpy as np
# in your case:
a, b = -1, 1
(b - a)*np.random.rand() + a
1
CypherX 21 grudzień 2019, 11:15
Zgadza się, są to te same instrukcje, które znajdują się w oficjalna dokumentacja. Cytat: (...). To sample Unif[a, b), b > a multiply the output of random by (b-a) and add a. (...)
 – 
Ícaro Pires
31 marzec 2021, 20:05