2013-05-01 24 views
7

Voglio creare un normale array distribuito con numpy.random.normal che consiste solo di valori positivi. Ad esempio il seguente illustra che a volte restituisce valori negativi e talvolta positivi. Come posso modificarlo in modo che restituisca solo valori positivi?Python numpy.random.normal solo valori positivi

>>> 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 ]) 
>>> 

Credo che avrei potuto risolverlo in qualche modo simile a questo:

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

Che cosa si intende per 'solo restituire valori positivi'? Cosa vuoi che faccia se restituisce un valore negativo? – Patashu

+0

Bene, vorrei modificare il codice in modo che restituisca solo valori positivi. – ustroetz

+1

Per definizione, una distribuzione normale si estende su tutti i possibili valori, positivi e negativi. Non è possibile conciliare la 'distribuzione normale' con 'solo valori positivi', quindi la mia domanda per voi è ... cosa volete VERAMENTE? – Patashu

risposta

7

La distribuzione normale, per definizione, si estende da -inf a + inf così quello che stai chiedendo non ha senso matematicamente .

È possibile eseguire una distribuzione normale e prendere il valore assoluto su "clip" su valori positivi, o semplicemente scartare valori negativi, ma è necessario comprendere che non sarà più una distribuzione normale.

1

È possibile sfalsare l'intero array del valore più basso (a sinistra) della matrice. Quello che ottieni potrebbe non essere veramente una "distribuzione normale", ma nell'ambito del tuo lavoro, occupandosi di array finito, puoi assicurarti che i valori siano positivi e si adattino a una curva a campana.

>>> 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

Suppongo che quello che vuoi dire è che si desidera modificare la densità di probabilità in modo che sia la stessa forma normale nel campo positivo e pari a zero in negativo. Questo è un caso pratico piuttosto comune. In tal caso, non puoi semplicemente prendere il valore assoluto delle variabili casuali normali generate. Invece, devi generare un nuovo numero normalmente distribuito indipendente fino a quando non ne trovi uno positivo. Un modo per farlo è ricorsivo, vedi sotto.

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

Questo è probabilmente ragionevole per alcuni casi d'uso, ma si noti che il campionamento da questa distribuzione sarà distorto verso valori più alti, specialmente se la media è vicino allo zero. Inoltre potresti essere in overflow se sei particolarmente sfortunato. – vroomfondel

+0

Sì, questa non è più una distribuzione normale, l'abbiamo modificata, ha un PDF diverso, troncato a zero. Ma penso che quella fosse la domanda, ed è spesso pratico farlo. Per quanto riguarda l'overflow dello stack in questo caso, nessuno è sfortunato a meno che non si disponga solo di pochi byte di RAM. –

+0

Per quanto riguarda l'overflow dello stack in questo caso, hai ragione se uno è interessato solo a una coda destra della distribuzione, cioè se la media della distribuzione è negativa per alcuni sigma. In tal caso, le prestazioni di questa soluzione si deterioreranno e finiranno per traboccare. Ma dubito che questo sia il caso d'uso previsto. È più di un attacco rapido. –

0

cosa sull'utilizzo di log-normale in queste righe:

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

    new_list = np.random.lognormal(mu, sigma, length_of_new_list) 
Problemi correlati