从scipy.stats…rvs和numpy.random中随机抽取的差异

2024-04-25 09:52:41 发布

您现在位置:Python中文网/ 问答频道 /正文

如果是相同的分布,那么从numpy.random中随机抽取样本比从scipy.stats.-.rvs中随机抽取样本要快。我想知道是什么原因造成了这两种速度的差异?


Tags: numpystats原因randomscipy差异速度样本
2条回答

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)

stats在检查错误和使接口更灵活方面有点开销。只要你不在一个循环中调用uniform.rvs,每次绘制的速度差应该是最小的。你可以一次得到所有的随机抽签,例如(1000万)

>>> rvs = stats.uniform.rvs(size=(10000, 1000))
>>> rvs.shape
(10000, 1000)

这是我不久前写的一个很长的答案:

scipy/numpy中的基本随机数是由 梅森捻线机在纽比。随机。的随机数 随机分布在cython/pyrex中,速度很快。

stats没有随机数生成器,随机数是 通过以下三种方式之一获得:

  • 直接从numpy.random,例如normal,t。。。相当快

  • 通过其他随机数的变换得到的随机数 在numpy.random中提供,速度也很快,因为它在 整个数字数组

  • 泛型:唯一的泛型生成随机数生成是由 使用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和scipy0.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来在循环中获得大量次的随机值。

相关问题 更多 >