Подтвердить что ты не робот

Разница между случайными ничьей из scipy.stats.... rvs и numpy.random

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

4b9b3361

Ответ 1

scipy.stats.uniform на самом деле использует numpy, вот соответствующая функция в статистике (mtrand является псевдонимом для numpy.random)

class uniform_gen(rv_continuous):
    def _rvs(self):
        return mtrand.uniform(0.0,1.0,self._size)

scipy.stats имеет немного накладных расходов для проверки ошибок и делает интерфейс более гибким. Разница в скорости должна быть минимальной, если вы не назовете uniform.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, например. normal, t,... довольно быстро

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

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

Ответ 2

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

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