我注意到下面的代码需要0.01秒,因为我需要它运行大约一百万次。
mydist = stats.norm(mean, 2)
for x in range(5,30):
probplak.append(mydist.pdf(x))
是否有其他方法可以得到类似的结果(一个值列表给出平均值和x值远离给出标准偏差的平均值?)。
答案 0 :(得分:4)
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
计算所有probplaks将比Python循环中对mydist.pdf
的一百万次调用快得多:
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