A partir de Python v3.6
, random.choices
podría usarse para devolver un list
elemento de tamaño específico de la población dada con pesos opcionales.
random.choices(population, weights=None, *, cum_weights=None, k=1)
población : list
contiene observaciones únicas. (Si está vacío, sube IndexError
)
pesos : más precisamente, los pesos relativos necesarios para realizar selecciones.
cum_weights : pesos acumulativos necesarios para realizar selecciones.
k : tamaño ( len
) de la list
salida. (Predeterminado len()=1
)
Pocas advertencias:
1) Utiliza muestreo ponderado con reemplazo para que los artículos extraídos sean reemplazados más tarde. Los valores en la secuencia de pesos en sí mismos no importan, pero su relación relativa sí.
A diferencia de lo np.random.choice
que solo puede asumir las probabilidades como ponderaciones y también lo que debe garantizar la suma de las probabilidades individuales hasta 1 criterio, aquí no existen tales regulaciones. Mientras pertenezcan a tipos numéricos ( int/float/fraction
excepto el Decimal
tipo), estos seguirían funcionando.
>>> 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 no se especifican ni pesos ni cum_weights , las selecciones se realizan con la misma probabilidad. Si se proporciona una secuencia de pesos , debe tener la misma longitud que la secuencia de población .
Especificar pesos y cum_weights plantea a TypeError
.
>>> random.choices(["white", "green", "red"], k=10)
['white', 'white', 'green', 'red', 'red', 'red', 'white', 'white', 'white', 'green']
3) cum_weights son típicamente el resultado de una itertools.accumulate
función que es realmente útil en tales situaciones.
De la documentación vinculada:
Internamente, los pesos relativos se convierten en pesos acumulativos antes de realizar selecciones, por lo que el suministro de los pesos acumulativos ahorra trabajo.
Por lo tanto, el suministro weights=[12, 12, 4]
o cum_weights=[12, 24, 28]
para nuestro caso artificial produce el mismo resultado y este último parece ser más rápido / eficiente.
random.choices
para llamadas individuales. Si necesita muchos resultados aleatorios, es realmente importante elegirlos todos a la vez ajustandonumber_of_items_to_pick
. Si lo hace, es un orden de magnitud más rápido.