with normal initialize array python numpy random scipy

python - normal - Diferencia entre sorteos aleatorios de scipy.stats... rvs y numpy.random



numpy random uniform (2)

Parece que si es la misma distribución, dibujar muestras aleatorias de numpy.random es más rápido que hacerlo desde scipy.stats.-.rvs . Me preguntaba ¿qué causa la diferencia de velocidad entre los dos?


scipy.stats.uniform realmente usa numpy, aquí está la función correspondiente en stats (mtrand es un alias para numpy.random)

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

scipy.stats tiene un poco de sobrecarga para la comprobación de errores y hace que la interfaz sea más flexible. La diferencia de velocidad debe ser mínima siempre que no llame a uniform.rvs en un bucle para cada extracción. Puede obtener todos los sorteos al azar a la vez, por ejemplo (10 millones)

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

Aquí está la respuesta larga, que escribí hace un tiempo:

Los números aleatorios básicos en scipy / numpy son creados por Mersenne-Twister PRNG en numpy.random. Los números aleatorios para las distribuciones en numpy.random están en cython / pyrex y son bastante rápidos.

scipy.stats no tiene un generador de números aleatorios, los números aleatorios se obtienen de una de estas tres formas:

  • directamente desde numpy.random, por ejemplo, normal, t, ... bastante rápido

  • números aleatorios por transformación de otros números aleatorios que están disponibles en numpy.random, también bastante rápido porque esto opera en matrices enteras de números

  • genérico: la única generación de números aleatorios de generación genérica es mediante el uso del ppf (cdf inverso) para transformar números aleatorios uniformes. Esto es relativamente rápido si hay una expresión explícita para el ppf, pero puede ser muy lenta si el ppf tiene que calcularse indirectamente. Por ejemplo, si solo se define el pdf, entonces el cdf se obtiene a través de la integración numérica y el ppf se obtiene a través de un solucionador de ecuaciones. Entonces algunas distribuciones son muy lentas


Me encontré con esto hoy y solo quería agregar algunos detalles de tiempo a esta pregunta. Vi lo que Joon mencionó donde, en particular, los números aleatorios de la distribución normal se generaron mucho más rápidamente con numpy que desde rvs en scipy.stats . Como se mencionó user333700, hay una sobrecarga con rvs pero si está generando una matriz de valores aleatorios, esa brecha se cierra en comparación con numpy . Aquí hay un ejemplo de tiempo 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)

Esto, en mi ejecución con numpy versión 1.11.1 y scipy 0.17.0, salidas:

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

Así que solo generar una muestra aleatoria de rvs fue casi 100 veces más lenta que usar numpy directamente. Sin embargo, si está generando una matriz de valores, la brecha se cierra (de 115 a 61,9 microsegundos).

Si puede evitarlo, probablemente no llame a rvs para obtener un valor aleatorio una tonelada de veces en un bucle.