À partir de Python v3.6
, random.choices
pourrait être utilisé pour renvoyer un list
des éléments de taille spécifiée à partir de la population donnée avec des poids facultatifs.
random.choices(population, weights=None, *, cum_weights=None, k=1)
population : list
contenant des observations uniques. (Si vide, soulève IndexError
)
poids : plus précisément les poids relatifs requis pour effectuer des sélections.
cum_weights : poids cumulatifs requis pour effectuer des sélections.
k : taille ( len
) de la list
sortie. (Par défaut len()=1
)
Quelques mises en garde:
1) Il utilise un échantillonnage pondéré avec remplacement afin que les éléments tirés soient remplacés plus tard. Les valeurs de la séquence de poids en elles-mêmes n'ont pas d'importance, mais leur rapport relatif le fait.
Contrairement à np.random.choice
ce qui ne peut prendre que des probabilités comme poids et qui doit également assurer la somme des probabilités individuelles jusqu'à 1 critère, il n'y a pas de telles réglementations ici. Tant qu'ils appartiennent à des types numériques ( int/float/fraction
sauf le Decimal
type), ceux-ci fonctionneront toujours.
>>> import random
# weights being integers
>>> random.choices(["white", "green", "red"], [12, 12, 4], k=10)
['green', 'red', 'green', 'white', 'white', 'white', 'green', 'white', 'red', 'white']
# weights being floats
>>> random.choices(["white", "green", "red"], [.12, .12, .04], k=10)
['white', 'white', 'green', 'green', 'red', 'red', 'white', 'green', 'white', 'green']
# weights being fractions
>>> random.choices(["white", "green", "red"], [12/100, 12/100, 4/100], k=10)
['green', 'green', 'white', 'red', 'green', 'red', 'white', 'green', 'green', 'green']
2) Si ni poids ni cum_weights ne sont spécifiés, les sélections sont effectuées avec une probabilité égale. Si une séquence de poids est fournie, elle doit être de la même longueur que la population séquence de .
La spécification à la fois des poids et des cum_weights soulève a TypeError
.
>>> random.choices(["white", "green", "red"], k=10)
['white', 'white', 'green', 'red', 'red', 'red', 'white', 'white', 'white', 'green']
3) cum_weights sont généralement le résultat d'une itertools.accumulate
fonction qui est vraiment pratique dans de telles situations.
De la documentation liée:
En interne, les poids relatifs sont convertis en poids cumulatifs avant d'effectuer des sélections, donc la fourniture des poids cumulatifs économise du travail.
Donc, soit l'approvisionnement weights=[12, 12, 4]
soit cum_weights=[12, 24, 28]
notre cas artificiel produit le même résultat et ce dernier semble être plus rapide / efficace.
random.choices
pour les appels individuels. Si vous avez besoin de beaucoup de résultats aléatoires, il est vraiment important de les choisir tous en même temps en les ajustantnumber_of_items_to_pick
. Si vous le faites, c'est un ordre de grandeur plus rapide.