Разница между случайными ничьями от scipy.stats .... rvs и numpy.random - PullRequest
11 голосов
/ 23 октября 2010

Похоже, что это то же самое распределение, отбор случайных выборок из numpy.random происходит быстрее, чем из scipy.stats.-.rvs. Мне было интересно, что вызывает разницу в скорости между двумя?

Ответы [ 2 ]

11 голосов
/ 23 октября 2010

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 имеет некоторые издержки для проверки ошибок и повышения гибкости интерфейса. Разница в скорости должна быть минимальной до тех пор, пока вы не будете вызывать файл shape.rvs в цикле для каждого розыгрыша. Вместо этого вы можете получить сразу все случайные розыгрыши, например (10 миллионов)

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

Вот длинный ответ, который я написал недавно:

Основные случайные числа в scipy / numpy создаются Мерсенн-Твистер PRNG в numpy.random. Случайные числа для дистрибутивы в numpy.random находятся в cython / pyrex и довольно быстрые.

scipy.stats не имеет генератора случайных чисел, случайные числа получается одним из трех способов:

  • непосредственно из numpy.random, например, нормально, т, ... довольно быстро

  • случайные числа путем преобразования других случайных чисел, которые доступно в numpy.random, также довольно быстро, потому что это работает на целые массивы чисел

  • generic: генерация случайных чисел генерируется только используя ppf (обратный cdf) для преобразования равномерных случайных чисел. Это относительно быстро, если есть явное выражение для ppf, но может быть очень медленным, если нужно вычислить ppf косвенно. Например, если определен только pdf, то cdf получены путем численного интегрирования и PPP получается через решатель уравнений. Так что некоторые дистрибутивы очень медленные.

6 голосов
/ 20 октября 2016

Я столкнулся с этим сегодня и просто хотел добавить некоторые детали времени к этому вопросу. Я видел, что упоминал Джун, где, в частности, случайные числа из нормального распределения генерировались намного быстрее с numpy, чем с rvs в scipy.stats. Как упомянул user333700, есть некоторые издержки с rvs, но если вы генерируете массив случайных значений, этот пробел закрывается по сравнению с numpy. Вот пример времени Юпитера:

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 была почти в 100 раз медленнее, чем использование numpy напрямую. Однако, если вы генерируете массив значений, пробел закрывается (от 115 до 61,9 микросекунд).

Если вы можете избежать этого, вероятно, не вызывайте rvs, чтобы получить одно случайное значение множество раз в цикле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...