how - Diferencias entre numpy.random y random.random en Python
random.choice python (3)
Tengo un gran script en Python. Me inspiré en el código de otras personas, así que terminé usando el módulo numpy.random
para algunas cosas (por ejemplo, para crear una matriz de números aleatorios tomados de una distribución binomial) y en otros lugares utilizo el módulo random.random
.
¿Puede alguien decirme las principales diferencias entre los dos? Mirando la página web del doc para cada uno de los dos, me parece que numpy.random
simplemente tiene más métodos, pero no tengo claro cómo la generación de los números aleatorios es diferente.
La razón por la que estoy preguntando es porque necesito sembrar mi programa principal para depuración. Pero no funciona a menos que use el mismo generador de números aleatorios en todos los módulos que estoy importando, ¿es correcto?
Además, leí aquí, en otra publicación, una discusión sobre NO usar numpy.random.seed()
, pero realmente no entendía por qué esta era una mala idea. Realmente apreciaría que alguien me explique por qué este es el caso.
¡Ya has hecho muchas observaciones correctas!
A menos que desee sembrar los dos generadores aleatorios, es probable que a la larga sea más simple elegir un generador u otro.
Para numpy.random.seed()
, la dificultad principal es que no es seguro para subprocesos, es decir, no es seguro de usar si tiene muchos subprocesos diferentes de ejecución , porque no se garantiza que funcione si se están ejecutando dos subprocesos diferentes la función al mismo tiempo. Si no está utilizando subprocesos, y si puede esperar razonablemente que no necesite volver a escribir su programa de esta manera en el futuro, numpy.random.seed()
debería estar bien. Si hay alguna razón para sospechar que puede necesitar hilos en el futuro, a la larga es mucho más seguro hacer lo que se sugiere y crear una instancia local de la clase numpy.random.Random
. Por lo que puedo decir, random.random.seed()
es seguro para subprocesos (o al menos, no he encontrado ninguna evidencia de lo contrario).
La biblioteca numpy.random
contiene algunas distribuciones de probabilidad adicionales comúnmente utilizadas en la investigación científica, así como un par de funciones de conveniencia para generar matrices de datos aleatorios. La biblioteca random.random
es un poco más liviana, y debería estar bien si no está haciendo investigación científica u otro tipo de trabajo en estadística.
De lo contrario, ambos usan la secuencia Twister de Mersenne para generar sus números aleatorios, y ambos son completamente deterministas, es decir, si conoce algunas partes clave de información, es posible predecir con certeza absoluta qué número vendrá después . Por esta razón, ninguno es adecuado para ningún uso criptográfico serio . Pero debido a que la secuencia es muy larga, ambas están bien para generar números aleatorios en los programas cotidianos. Esta es también la razón de la necesidad de sembrar el valor aleatorio: si comienzas en el mismo lugar cada vez, siempre obtendrás la misma secuencia de números aleatorios.
Como nota al margen, si necesita aleatoriedad de nivel criptográfico, debe usar el módulo de secrets , o algo así como Crypto.Random si está utilizando una versión de Python anterior a Python 3.6.
Desde Python for Data Analysis , el módulo numpy.random
complementa al Python al random
con funciones para generar de manera eficiente matrices enteras de valores de muestra de muchos tipos de distribuciones de probabilidad.
Por el contrario, el módulo random
incorporado de Python solo muestra un valor a la vez, mientras que numpy.random
puede generar una muestra muy grande más rápido. Usando la función mágica de IPython %timeit
uno puede ver qué módulo funciona más rápido:
In [1]: from random import normalvariate
In [2]: N = 1000000
In [3]: %timeit samples = [normalvariate(0, 1) for _ in xrange(N)]
1 loop, best of 3: 963 ms per loop
In [4]: %timeit np.random.normal(size=N)
10 loops, best of 3: 38.5 ms per loop
La fuente de la semilla y el perfil de distribución utilizado van a afectar las salidas. Si está buscando la aleatoriedad criptológica, la siembra de os.urandom () obtendrá bytes aleatorios casi reales de la conversación del dispositivo (es decir, ethernet o disco) (es decir, / dev / random en BSD)
esto evitará que proporciones una semilla y así generes números aleatorios deterministas. Sin embargo, las llamadas aleatorias le permiten ajustar los números a una distribución (lo que yo llamo azar científico). Eventualmente, lo único que desea es una distribución de números aleatorios de la curva de campana, numpy es lo mejor para dilucidar esto.
ASÍ, sí, quédese con un generador, pero decida qué azar quiere: aleatorio, pero definitivamente desde una curva de distrubtución, o tan aleatorio como pueda obtener sin un dispositivo cuántico.