Итерация, вызывающая stats.norm.pdf (), работает медленно - PullRequest
0 голосов
/ 15 мая 2018

Я заметил, что следующий код занимает 0,01 секунды, что слишком много, учитывая, что мне нужно, чтобы он выполнялся миллион раз.

mydist = stats.norm(mean, 2)
for x in range(5,30):               
     probplak.append(mydist.pdf(x))

Есть ли другой способ получить аналогичный результат (список значений, дающих среднее значение и значения х, отличные от среднего, дающего стандартное отклонение?).

1 Ответ

0 голосов
/ 15 мая 2018

mydist.pdf может быть передана последовательность значений вместо одного скаляра:

probplak = mydist.pdf(range(5, 30))

Это дает результат намного быстрее, чем использование цикла for.

Например,

import scipy.stats as stats
mean = 15
mydist = stats.norm(mean, 2)
probplak = mydist.pdf(range(5, 30))
# array([7.43359757e-07, 7.99187055e-06, 6.69151129e-05, 4.36341348e-04,
#        2.21592421e-03, 8.76415025e-03, 2.69954833e-02, 6.47587978e-02,
#        1.20985362e-01, 1.76032663e-01, 1.99471140e-01, 1.76032663e-01,
#        1.20985362e-01, 6.47587978e-02, 2.69954833e-02, 8.76415025e-03,
#        2.21592421e-03, 4.36341348e-04, 6.69151129e-05, 7.99187055e-06,
#        7.43359757e-07, 5.38488002e-08, 3.03794142e-09, 1.33477831e-10,
#        4.56736020e-12])

Использование IPython для сравнения скорости:

In [112]: %timeit mydist.pdf(range(5, 30))              # <-- passing sequence
10000 loops, best of 3: 134 µs per loop

In [113]: %timeit [mydist.pdf(x) for x in range(5,30)]  # <-- using a loop
100 loops, best of 3: 2.95 ms per loop

Также обратите внимание, что stats.norm.pdf можно передавать в виде массивов аргументов не только для x, но и для loc (то есть mean) и scale (то есть стандартное отклонение) , Это означает, что если вам нужно запустить этот код на миллион разные средства и масштабы, то вы могли бы вычислить все probplak с одним вызовом stats.norm.pdf:

means = [1,2,3]
std_devs = [10,20,30]
probplaks = stats.norm.pdf(np.arange(5, 30)[:,None], means, std_devs)

возвращает массив формы (25, 3). Если вы измените means и std_devs на списки с миллионными значениями, тогда probplaks.shape будет (25, 10**6).

Вычисление всех проблаков одним вызовом stats.norm.pdf будет намного быстрее, чем миллион вызовов mydist.pdf в цикле Python:

In [117]: %timeit stats.norm.pdf(np.arange(5, 30)[:,None], means, scales)
10000 loops, best of 3: 135 µs per loop

In [118]: %timeit [[stats.norm(m, s).pdf(x) for x in range(5,30)] for m,s in zip(means,scales)]
10 loops, best of 3: 64.4 ms per loop
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...