Comment puis-je générer des nombres aléatoires non répétitifs dans numpy?
list = np.random.random_integers(20,size=(10))
Comment puis-je générer des nombres aléatoires non répétitifs dans numpy?
list = np.random.random_integers(20,size=(10))
Réponses:
numpy.random.Generator.choice
offre un replace
argument pour échantillonner sans remplacement:
from numpy.random import default_rng
rng = default_rng()
numbers = rng.choice(20, size=10, replace=False)
Si vous utilisez un NumPy antérieur à la version 1.17, sans l' Generator
API, vous pouvez utiliser à random.sample()
partir de la bibliothèque standard:
print(random.sample(range(20), 10))
Vous pouvez également utiliser numpy.random.shuffle()
et trancher, mais ce sera moins efficace:
a = numpy.arange(20)
numpy.random.shuffle(a)
print a[:10]
Il y a aussi un replace
argument dans la numpy.random.choice
fonction héritée , mais cet argument a été implémenté de manière inefficace puis laissé inefficace en raison des garanties de stabilité du flux de nombres aléatoires, son utilisation n'est donc pas recommandée. (Il fait essentiellement la chose shuffle-and-slice en interne.)
import random
?
random.sample(range(n), 10))
sera efficace même pour les très gros n
, puisqu'un range
objet n'est qu'un petit wrapper stockant les valeurs de démarrage, d'arrêt et d'étape, mais ne crée pas la liste complète des entiers. Dans Python 2, vous pouvez remplacer range
par xrange
pour obtenir un comportement similaire.
Je pense que numpy.random.sample
ça ne marche pas bien maintenant. C'est mon chemin:
import numpy as np
np.random.choice(range(20), 10, replace=False)
range(n)
(ou arange(n)
) comme premier argument de choice
, cela équivaut à simplement passer n
, par exemple choice(20, 10, replace=False)
.
np.random.choice(a, size, replace=False)
c'est très lent pour les gros a
- sur ma machine, environ 30 ms pour a = 1M.
n
utilisation numpy.random.Generator.choice
(à partir de numpy v1.17)
Des années plus tard, il est temps de choisir 40000 sur 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
(Pourquoi choisir 40000 sur 10000 ^ 2? Pour générer de grandes
matrices scipy.sparse.random - scipy 1.4.1 utilise np.random.choice( replace=False )
, slooooow.)
Astuce du chapeau pour les gens numpy.random.
Générez simplement un tableau contenant la plage de nombres requise, puis mélangez-les en échangeant à plusieurs reprises un tableau aléatoire avec le 0e élément du tableau. Cela produit une séquence aléatoire qui ne contient pas de valeurs en double.