【发布时间】:2011-04-29 10:20:51
【问题描述】:
如果是相同的分布,从numpy.random 抽取随机样本似乎比从scipy.stats.-.rvs 抽取随机样本要快。我想知道是什么导致了两者之间的速度差异?
【问题讨论】:
如果是相同的分布,从numpy.random 抽取随机样本似乎比从scipy.stats.-.rvs 抽取随机样本要快。我想知道是什么导致了两者之间的速度差异?
【问题讨论】:
scipy.stats.uniform其实用的是numpy,这里是stats中对应的函数(mtrand是numpy.random的别名)
class uniform_gen(rv_continuous):
def _rvs(self):
return mtrand.uniform(0.0,1.0,self._size)
scipy.stats 在错误检查和使界面更灵活方面有一些开销。只要您不在每次绘制的循环中调用 uniform.rvs,速度差异应该是最小的。相反,您可以一次获得所有随机抽奖,例如(1000 万)
>>> rvs = stats.uniform.rvs(size=(10000, 1000))
>>> rvs.shape
(10000, 1000)
这是我不久前写的长答案:
scipy/numpy 中的基本随机数是由 numpy.random 中的 Mersenne-Twister PRNG。随机数为 numpy.random 中的分布在 cython/pyrex 中并且非常快。
scipy.stats 没有随机数生成器,随机数是 通过以下三种方式之一获得:
直接来自 numpy.random,例如正常,t,...相当快
通过转换其他随机数得到的随机数 在 numpy.random 中可用,也非常快,因为它在 整个数字数组
generic:唯一的泛型生成随机数是由 使用 ppf(逆 cdf)来变换均匀随机数。 如果有明确的表达式,则相对较快 ppf,但如果必须计算 ppf,可能会非常慢 间接地。例如,如果只定义了 pdf,那么 cdf 是 通过数值积分获得,ppf 是通过 方程求解器。所以有些发行版很慢。
【讨论】:
我今天遇到了这个问题,只是想为这个问题添加一些时间细节。我看到 joon 提到的地方,特别是,使用numpy 生成的正态分布随机数比scipy.stats 中的rvs 生成的随机数要快得多。正如 user333700 所提到的,rvs 存在一些开销,但如果您正在生成一个随机值数组,那么与numpy 相比,该差距会缩小。这是一个 jupyter 计时示例:
from scipy.stats import norm
import numpy as np
n = norm(0, 1)
%timeit -n 1000 n.rvs(1)[0]
%timeit -n 1000 np.random.normal(0,1)
%timeit -n 1000 a = n.rvs(1000)
%timeit -n 1000 a = [np.random.normal(0,1) for i in range(0, 1000)]
%timeit -n 1000 a = np.random.randn(1000)
在我使用numpy 1.11.1 版和scipy 0.17.0 运行时,输出:
1000 loops, best of 3: 46.8 µs per loop
1000 loops, best of 3: 492 ns per loop
1000 loops, best of 3: 115 µs per loop
1000 loops, best of 3: 343 µs per loop
1000 loops, best of 3: 61.9 µs per loop
因此,仅从 rvs 生成一个随机样本几乎比直接使用 numpy 慢 100 倍。但是,如果您正在生成一个值数组,那么差距就会缩小(115 到 61.9 微秒)。
如果可以避免,可能不要调用rvs 在循环中多次获取一个随机值。
【讨论】: