Начиная с Python v3.6
, random.choices
может использоваться для возврата list
элементов заданного размера из заданной совокупности с необязательными весами.
random.choices(population, weights=None, *, cum_weights=None, k=1)
население : list
содержит уникальные наблюдения. (Если пусто, поднимает IndexError
)
веса : точнее относительные веса, необходимые для выбора.
cum_weights : совокупные веса, необходимые для выбора.
k : размер ( len
) объекта list
для вывода. (По умолчанию len()=1
)
Несколько предостережений:
1) Используется взвешенная выборка с заменой, чтобы вытянутые элементы впоследствии были заменены. Значения в последовательности весов сами по себе не имеют значения, но их относительное соотношение имеет значение.
В отличие от того, np.random.choice
который может принимать только вероятности в качестве весов, а также который должен обеспечивать суммирование индивидуальных вероятностей до 1 критерия, здесь нет таких правил. Пока они принадлежат числовым типам ( int/float/fraction
кроме Decimal
типа), они все равно будут работать.
>>> 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) Если ни веса, ни cum_weights не указаны, выборы делаются с равной вероятностью. Если указана последовательность весов , она должна быть той же длины, что и последовательность совокупности .
Задание весов и cum_weights повышает a TypeError
.
>>> random.choices(["white", "green", "red"], k=10)
['white', 'white', 'green', 'red', 'red', 'red', 'white', 'white', 'white', 'green']
3) cum_weights обычно являются результатом itertools.accumulate
функции, которая действительно удобна в таких ситуациях.
Из документации связано:
Внутренне, относительные веса преобразуются в кумулятивные веса, прежде чем делать выбор, поэтому предоставление кумулятивных весов экономит работу.
Таким образом, либо поставка, weights=[12, 12, 4]
либо cum_weights=[12, 24, 28]
для нашего надуманного дела дает тот же результат, и последний кажется более быстрым / эффективным.
random.choices
для отдельных вызовов. Если вам нужно много случайных результатов, очень важно выбрать их все сразу, настроивnumber_of_items_to_pick
. Если вы это сделаете, это будет на порядок быстрее.