repetir - Crear una lista aleatoria de enteros en Python
lista de numeros aleatorios en python (4)
Me gustaría crear una lista aleatoria de enteros para fines de prueba. La distribución de los números no es importante. Lo único que cuenta es el tiempo . Sé que generar números aleatorios es una tarea que consume tiempo, pero debe haber una mejor manera.
Aquí está mi solución actual:
import random
import timeit
# random lists from [0-999] interval
print [random.randint(0,1000) for r in xrange(10)] # v1
print [random.choice([i for i in xrange(1000)]) for r in xrange(10)] # v2
# measurement:
t1 = timeit.Timer(''[random.randint(0,1000) for r in xrange(10000)]'',''import random'') # v1
t2 = timeit.Timer(''random.sample(range(1000), 10000)'',''import random'') # v2
print t1.timeit(1000)/1000
print t2.timeit(1000)/1000
v2 es más rápido que v1 pero no funciona a gran escala. Da el siguiente error: '' ValueError: sample larger than population ''
¿Conoces una solución rápida y eficiente que funcione en esa escala?
Editar:
Andrew''s: 0.000290962934494
gnibbler''s: 0.0058455221653
KennyTM''s: 0.00219276118279
NumPy vino, vio, conquistó
¡Gracias!
En primer lugar, debe usar randrange(0,1000)
o randint(0,999)
, no randint(0,1000)
. El límite superior de randint
es inclusivo.
Para eficientemente, randint
es simplemente una envoltura de randrange
que llama al random
, por lo que debe usar al random
. Además, use xrange
como argumento para sample
, no range
.
Podrías usar
[a for a in sample(xrange(1000),1000) for _ in range(10000/1000)]
para generar 10 000 números en el rango con la sample
10 veces.
(Por supuesto, esto no le ganará a NumPy).
$ python2.7 -m timeit -s ''from random import randrange'' ''[randrange(1000) for _ in xrange(10000)]''
10 loops, best of 3: 26.1 msec per loop
$ python2.7 -m timeit -s ''from random import sample'' ''[a%1000 for a in sample(xrange(10000),10000)]''
100 loops, best of 3: 18.4 msec per loop
$ python2.7 -m timeit -s ''from random import random'' ''[int(1000*random()) for _ in xrange(10000)]''
100 loops, best of 3: 9.24 msec per loop
$ python2.7 -m timeit -s ''from random import sample'' ''[a for a in sample(xrange(1000),1000) for _ in range(10000/1000)]''
100 loops, best of 3: 3.79 msec per loop
$ python2.7 -m timeit -s ''from random import shuffle
> def samplefull(x):
> a = range(x)
> shuffle(a)
> return a'' ''[a for a in samplefull(1000) for _ in xrange(10000/1000)]''
100 loops, best of 3: 3.16 msec per loop
$ python2.7 -m timeit -s ''from numpy.random import randint'' ''randint(1000, size=10000)''
1000 loops, best of 3: 363 usec per loop
Pero como no te importa la distribución de números, ¿por qué no utilizar simplemente:
range(1000)*(10000/1000)
?
No está del todo claro lo que quieres, pero usaría numpy.random.randint :
import numpy.random as nprnd
import timeit
t1 = timeit.Timer(''[random.randint(0,1000) for r in xrange(10000)]'',''import random'') # v1
### change v2 so that it picks numbers in (0,10000) and thus runs...
t2 = timeit.Timer(''random.sample(range(10000), 10000)'',''import random'') # v2
t3 = timeit.Timer(''nprnd.randint(1000, size=10000)'',''import numpy.random as nprnd'') # v3
print t1.timeit(1000)/1000
print t2.timeit(1000)/1000
print t3.timeit(1000)/1000
que da en mi máquina
0.0233682730198
0.00781716918945
0.000147947072983
Tenga en cuenta que randint es muy diferente de random.sample (para que funcione en su caso, tuve que cambiar los 1,000 a 10,000 como señaló uno de los comentaristas - si realmente los quiere de 0 a 1,000, podría dividir por 10). Y si realmente no te importa qué distribución estás recibiendo, entonces es posible que no entiendas tu problema muy bien, o números aleatorios, con disculpas si eso suena grosero ...
Su pregunta sobre el rendimiento es discutible: ambas funciones son muy rápidas. La velocidad de su código estará determinada por lo que haga con los números aleatorios.
Sin embargo, es importante que comprenda la diferencia en el comportamiento de esas dos funciones. Uno hace un muestreo aleatorio con reemplazo, el otro toma muestras al azar sin reemplazo.
Todos los métodos aleatorios terminan llamando a random.random()
así que la mejor manera es llamarlo directamente
[int(1000*random.random()) for i in xrange(10000)]
p.ej.
random.randint
llamadas random.randrange
random.randrange
tiene un montón de sobrecarga para verificar el rango antes de regresar a istart + istep*int(self.random() * n)
Editar: numpy es mucho más rápido, por supuesto, por supuesto