Come posso generare numeri casuali non ripetitivi in numpy?
list = np.random.random_integers(20,size=(10))
Come posso generare numeri casuali non ripetitivi in numpy?
list = np.random.random_integers(20,size=(10))
Risposte:
numpy.random.Generator.choice
offre un replace
argomento per campionare senza sostituzione:
from numpy.random import default_rng
rng = default_rng()
numbers = rng.choice(20, size=10, replace=False)
Se sei su NumPy precedente alla 1.17, senza Generator
API, puoi utilizzare random.sample()
dalla libreria standard:
print(random.sample(range(20), 10))
Puoi anche usare numpy.random.shuffle()
e affettare, ma questo sarà meno efficiente:
a = numpy.arange(20)
numpy.random.shuffle(a)
print a[:10]
C'è anche un replace
argomento nella numpy.random.choice
funzione legacy , ma questo argomento è stato implementato in modo inefficiente e quindi lasciato inefficiente a causa delle garanzie di stabilità del flusso di numeri casuali, quindi il suo utilizzo non è raccomandato. (Fondamentalmente fa la cosa shuffle-and-slice internamente.)
random.sample(range(n), 10))
sarà efficiente anche per le dimensioni molto grandi n
, poiché un range
oggetto è solo un piccolo wrapper che memorizza i valori di avvio, arresto e passaggio, ma non crea l'elenco completo degli interi. In Python 2, puoi sostituire range
con xrange
per ottenere un comportamento simile.
Penso numpy.random.sample
che non funzioni adesso. Questo è il mio modo:
import numpy as np
np.random.choice(range(20), 10, replace=False)
range(n)
(o arange(n)
) come primo argomento di choice
, è equivalente a passare n
, ad es choice(20, 10, replace=False)
.
np.random.choice(a, size, replace=False)
è molto lento per i grandi a
: sulla mia macchina, circa 30 ms per a = 1M.
n
uso molto ampio numpy.random.Generator.choice
(a partire da numpy v1.17)
Anni dopo, alcuni tempi per scegliere 40000 su 10000 ^ 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
(Perché scegliere 40000 di 10000 ^ 2 per generare grandi?
Scipy.sparse.random
matrici - SciPy 1.4.1 usi np.random.choice( replace=False )
., Slooooow)
Punta del cappello a numpy.random people.
È possibile utilizzare la conversione di set list in Python. 10 numeri univoci compresi tra 0 e 20 possono essere ottenuti come:
import numpy as np
import random
unique_numbers=set()
while(len(unique_numbers)<10):
unique_numbers.add(np.random.randint(0,20))
unique_numbers=list(unique_numbers)
random.shuffle(unique_numbers)
print(unique_numbers)
Genera semplicemente un array che contiene l'intervallo di numeri richiesto, quindi mescolali scambiandone ripetutamente uno casuale con l'elemento 0 nell'array. Questo produce una sequenza casuale che non contiene valori duplicati.