2013-05-01 11 views
7

Chcę utworzyć normalną rozproszoną tablicę z numpy.random.normal, która składa się tylko z wartości dodatnich. Na przykład poniższe ilustruje, że czasami daje wartości ujemne, a czasem dodatnie. Jak mogę go zmodyfikować, aby przywracał tylko wartości dodatnie?Python numpy.random.normal tylko pozytywne wartości

>>> import numpy 
>>> numpy.random.normal(10,8,3) 
array([ -4.98781629, 20.12995344, 4.7284051 ]) 
>>> numpy.random.normal(10,8,3) 
array([ 17.71918829, 15.97617052, 1.2328115 ]) 
>>> 

Chyba mogę go rozwiązać jakoś tak:

myList = numpy.random.normal(10,8,3) 

while item in myList <0: 
     # run again until all items are positive values 
     myList = numpy.random.normal(10,8,3) 
+0

Co masz na myśli przez 'tylko oddać wartości dodatnie'? Co chcesz zrobić, jeśli zwróci wartość ujemną? – Patashu

+0

Chciałbym zmodyfikować kod tak, aby zwracał tylko wartości dodatnie. – ustroetz

+1

Z definicji rozkład normalny rozciąga się na wszystkie możliwe wartości, dodatnie i ujemne. Nie można pogodzić "rozkładu normalnego" z "tylko wartościami dodatnimi", więc moje pytanie do ciebie jest ... czego NAPRAWDĘ chcesz? – Patashu

Odpowiedz

7

Rozkład normalny, z definicji, rozciąga się od inf do + inf więc co prosicie nie ma sensu matematycznego .

Możesz przyjąć rozkład normalny i przyjąć wartość bezwzględną, aby "przypiąć" do wartości dodatnich, lub po prostu odrzucić wartości ujemne, ale należy zrozumieć, że nie będzie to już rozkład normalny.

1

Możesz przesunąć całą tablicę o najniższą wartość (najbardziej po lewej stronie) tablicy. To, co dostajesz, może nie być prawdziwie "normalną dystrybucją", ale w ramach twojej pracy, zajmując się skończoną tablicą, możesz zapewnić, że wartości są dodatnie i mieszczą się pod krzywą dzwonową.

>>> mu,sigma = (0,1.0) 
>>> s = np.random.normal(mu, 1.0, 100) 
>>> s 
array([-0.58017653, 0.50991809, -1.13431539, -2.34436721, -1.20175652, 
     0.56225648, 0.66032708, -0.98493441, 2.72538462, -1.28928887]) 
>>> np.min(s) 
-2.3443672118476226 
>>> abs(np.min(s)) 
2.3443672118476226 
>>> np.add(s,abs(np.min(s))) 
array([ 1.76419069, 2.85428531, 1.21005182, 0.  , 1.14261069, 
     2.90662369, 3.00469429, 1.3594328 , 5.06975183, 1.05507835]) 
0

Przypuszczam, że to, co masz na myśli to, że chcesz zmodyfikować gęstość prawdopodobieństwa taka, że ​​jest to ten sam kształt, jak zwykle w dodatnim zakresie, a zero w negatywie. To dość powszechny przypadek praktyczny. W takim przypadku nie można po prostu przyjąć bezwzględnej wartości wygenerowanych normalnych zmiennych losowych. Zamiast tego musisz wygenerować nowy niezależny, normalnie rozproszony numer, dopóki nie uzyskasz pozytywnego wyniku. Jednym ze sposobów, aby to zrobić jest rekursywnie, patrz poniżej.

import numpy as np def PosNormal(mean, sigma): x = np.random.normal(xbar,delta_xbar,1) return(x if x>=0 else PosNormal(mean,sigma))

+0

Jest to prawdopodobnie uzasadnione w niektórych przypadkach użycia, ale zauważ, że próbkowanie z tego rozkładu będzie nastawione na wyższe wartości, szczególnie jeśli średnia jest blisko zera. Również możesz mieć przepełnienie stosu, jeśli masz szczególnie pecha. – vroomfondel

+0

Tak, to nie jest już normalna dystrybucja, zmieniliśmy ją, ma inny plik PDF, obcięty na zero. Ale myślę, że to było pytanie i często jest to praktyczne. Dotyczy obaw o przepełnienie stosu w tym przypadku, nikt nie jest TAK pechowy, chyba że masz tylko kilka bajtów pamięci RAM. –

+0

Jeśli chodzi o twoje obawy związane z przepełnieniem stosu w tym przypadku, masz rację, jeśli interesuje cię tylko prawy tył kilku sigma, to znaczy, jeśli średnia rozkładu jest ujemna o kilka sigm. W takim przypadku wydajność tego rozwiązania ulegnie pogorszeniu i ostatecznie ulegnie przepełnieniu. Ale wątpię, czy to jest zamierzony przypadek użycia. To raczej szybki hack. –

0

co o używaniu lognormal wzdłuż tych linii:

mu = np.mean(np.log(list)) 
    sigma = np.std(np.log(list)) 

    new_list = np.random.lognormal(mu, sigma, length_of_new_list) 
Powiązane problemy