【问题标题】:Difference between random draws from scipy.stats....rvs and numpy.random来自 scipy.stats....rvs 和 numpy.random 的随机抽取之间的区别
【发布时间】:2011-04-29 10:20:51
【问题描述】:

如果是相同的分布,从numpy.random 抽取随机样本似乎比从scipy.stats.-.rvs 抽取随机样本要快。我想知道是什么导致了两者之间的速度差异?

【问题讨论】:

    标签: python numpy random scipy


    【解决方案1】:

    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 是通过 方程求解器。所以有些发行版很慢。

    【讨论】:

    • 谢谢。我正在运行 MCMC 例程,所以我必须反复绘制很多东西,所以我将使用 numpy.random。
    【解决方案2】:

    我今天遇到了这个问题,只是想为这个问题添加一些时间细节。我看到 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 在循环中多次获取一个随机值。

    【讨论】:

      猜你喜欢
      • 2021-01-07
      • 2017-12-02
      • 1970-01-01
      • 2013-01-12
      • 2011-10-25
      • 1970-01-01
      • 1970-01-01
      • 2017-12-24
      相关资源
      最近更新 更多