2013-05-01 3 views
7

Я хочу создать нормальный распределенный массив с numpy.random.normal, который состоит только из положительных значений. Например, следующее показывает, что оно иногда возвращает отрицательные значения, а иногда и положительные. Как я могу изменить его, чтобы он возвращал только положительные значения?Python numpy.random.normal только положительные значения

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

Я предполагаю, что я мог бы решить эту проблему как-то так:

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

Что вы имеете в виду под "только вернуть положительные значения? Что вы хотите сделать, если оно вернет отрицательное значение? – Patashu

+0

Ну, я хотел бы изменить код, чтобы он только возвращал положительные значения. – ustroetz

+1

По определению нормальное распределение распространяется на все возможные значения, положительные и отрицательные. Вы не можете примирить «нормальное распределение» с «только положительными значениями», поэтому мой вопрос к вам ... что вы действительно хотите? – Patashu

ответ

7

Нормальное распределение, по определению, простирается от -inf до + инф так, что вы просите не имеет смысла математически ,

Вы можете принять нормальное распределение и принять абсолютное значение «клип» на положительные значения или просто отбросить отрицательные значения, но вы должны понимать, что он больше не будет нормальным распределением.

1

Вы можете компенсировать весь ваш массив наименьшим значением (слева) от массива. То, что вы получаете, может быть не совсем «нормальным распределением», но в рамках вашей работы, касающейся конечного массива, вы можете убедиться, что значения положительны и соответствуют кривой колокола.

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

Я предполагаю, что вы имеете в виду, что вы хотите изменить плотность вероятности таким образом, что она имеет такую ​​же форму, как обычно в положительном диапазоне, и нуль в отрицательном. Это довольно распространенный практический случай. В таком случае вы не можете просто взять абсолютное значение генерируемых нормальных случайных величин. Вместо этого вы должны создать новое независимое нормально распределенное число, пока не придумаете положительный. Один из способов сделать это рекурсивно, см. Ниже.

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

Это, вероятно, разумно для некоторых случаев использования, но обратите внимание, что выборка из этого распределения будет смещена в сторону более высоких значений, особенно если среднее значение около нуля. Кроме того, вы можете получить переполнение стека, если вам особенно не повезло. – vroomfondel

+0

Да, это уже не нормальное распространение, мы изменили его, у него другой PDF, усеченный на ноль. Но я думаю, что это был вопрос, и это часто бывает практичным. Что касается вашего беспокойства по поводу переполнения стека в этом случае, никто этого не повезет, если у вас всего несколько байт ОЗУ. –

+0

Что касается вашего беспокойства о переполнении стека в этом случае, вы правы, если вас интересует только правый хвост только для сигмы, т. Е. Если среднее значение распределения отрицательно для нескольких сигм. В этом случае производительность этого решения будет ухудшаться и, в конечном счете, будет переполняться. Но я сомневаюсь, что это предполагаемый прецедент. Это скорее быстрый взлом. –

0

что об использовании Логнормальное вдоль этих линий:

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

    new_list = np.random.lognormal(mu, sigma, length_of_new_list) 
Смежные вопросы