Como posso gerar números aleatórios não repetitivos em numpy?
list = np.random.random_integers(20,size=(10))
random
numpy
numbers
non-repetitive
Academia
fonte
fonte
Respostas:
numpy.random.Generator.choice
oferece umreplace
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 arandom.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 nanumpy.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.)fonte
import random
?random.sample(range(n), 10))
será eficiente mesmo para muito grandesn
, já que umrange
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 substituirrange
porxrange
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)
fonte
range(n)
(ouarange(n)
) como o primeiro argumento dechoice
, é equivalente a apenas passarn
, por exemplochoice(20, 10, replace=False)
.np.random.choice(a, size, replace=False)
é muito lento para grandesa
- na minha máquina, cerca de 30 ms para a = 1M.n
uso muito grandenumpy.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.
fonte
Você também pode conseguir isso classificando:
random_numbers = np.random.random([num_samples, max_int]) samples = np.argsort(random_numbers, axis=1)
fonte
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.
fonte