Como posso gerar números aleatórios não repetitivos em numpy?
list = np.random.random_integers(20,size=(10))
Como posso gerar números aleatórios não repetitivos em numpy?
list = np.random.random_integers(20,size=(10))
Respostas:
numpy.random.Generator.choice
oferece um replace
argumento para provar sem substituição:
from numpy.random import default_rng
rng = default_rng()
numbers = rng.choice(20, size=10, replace=False)
Se você estiver em um NumPy anterior ao 1.17, sem a Generator
API, você pode usar a random.sample()
partir da biblioteca padrão:
print(random.sample(range(20), 10))
Você também pode usar numpy.random.shuffle()
e fatiar, mas será menos eficiente:
a = numpy.arange(20)
numpy.random.shuffle(a)
print a[:10]
Também há um replace
argumento na numpy.random.choice
função de legado , mas esse argumento foi implementado de maneira ineficiente e, em seguida, deixado ineficiente devido às garantias de estabilidade do fluxo de número aleatório, portanto, seu uso não é recomendado. (Basicamente, ele faz o shuffle-and-slice internamente.)
import random
?
random.sample(range(n), 10))
será eficiente mesmo para muito grandes n
, já que um range
objeto é apenas um pequeno invólucro que armazena valores de início, parada e etapa, mas não cria a lista completa de inteiros. No Python 2, você pode substituir range
por xrange
para obter um comportamento semelhante.
Acho numpy.random.sample
que não funciona direito agora. Esta é a minha maneira:
import numpy as np
np.random.choice(range(20), 10, replace=False)
range(n)
(ou arange(n)
) como o primeiro argumento de choice
, é equivalente a apenas passar n
, por exemplo choice(20, 10, replace=False)
.
np.random.choice(a, size, replace=False)
é muito lento para grandes a
- na minha máquina, cerca de 30 ms para a = 1M.
n
uso muito grande numpy.random.Generator.choice
(começando com numpy v1.17)
Anos depois, algum tempo é necessário para escolher 40.000 de 10.000 ^ 2 (Numpy 1.8.1, imac 2.7 GHz):
import random
import numpy as np
n = 10000
k = 4
np.random.seed( 0 )
%timeit np.random.choice( n**2, k * n, replace=True ) # 536 µs ± 1.58 µs
%timeit np.random.choice( n**2, k * n, replace=False ) # 6.1 s ± 9.91 ms
# https://docs.scipy.org/doc/numpy/reference/random/index.html
randomstate = np.random.default_rng( 0 )
%timeit randomstate.choice( n**2, k * n, replace=False, shuffle=False ) # 766 µs ± 2.18 µs
%timeit randomstate.choice( n**2, k * n, replace=False, shuffle=True ) # 1.05 ms ± 1.41 µs
%timeit random.sample( range( n**2 ), k * n ) # 47.3 ms ± 134 µs
(Por que escolher 40000 de 10000 ^ 2? Para gerar
matrizes scipy.sparse.random grandes
- scipy 1.4.1 usa np.random.choice( replace=False )
, slooooow.)
Ponta do chapéu para pessoas numpy.random.
Simplesmente gere um array que contenha o intervalo de números necessário e embaralhe-os trocando repetidamente um aleatório pelo 0º elemento do array. Isso produz uma sequência aleatória que não contém valores duplicados.