Начиная с Python v3.6
, random.choices
можно было бы использовать для возврата list
элементов заданного размера из данной популяции с дополнительными весами.
blockquote>
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 вызывает
TypeError
.>>> random.choices(["white", "green", "red"], k=10) ['white', 'white', 'green', 'red', 'red', 'red', 'white', 'white', 'white', 'green']
3) cum_weights обычно являются результатом функции
itertools.accumulate
, которые действительно удобны в таких ситуациях.Из связанной документации:
Внутренне относительные веса преобразуются в кумулятивные веса перед выбором, поэтому загрузка кумулятивных весов экономит работу.
blockquote>Таким образом, либо поставка
weights=[12, 12, 4]
, либоcum_weights=[12, 24, 28]
для нашего надуманного случая дает один и тот же результат, а последний, по-видимому, работает быстрее / эффективнее.