小编典典

生成具有给定(数值)分布的随机数

all

我有一个文件,其中包含不同值的一些概率,例如:

1 0.1
2 0.05
3 0.05
4 0.2
5 0.4
6 0.2

我想使用这个分布生成随机数。是否存在处理此问题的现有模块?自己编写代码相当简单(构建累积密度函数,生成随机值 [0,1]
并选择相应的值)但看起来这应该是一个常见问题,并且可能有人已经创建了一个函数/模块它。

我需要这个,因为我想生成一个生日列表(不遵循标准random模块中的任何分布)。


阅读 63

收藏
2022-06-30

共1个答案

小编典典

scipy.stats.rv_discrete可能是你想要的。您可以通过values参数提供概率。然后您可以使用rvs()分布对象的方法来生成随机数。

正如 Eugene Pakhomov
在评论中指出的那样,您还可以将p关键字参数传递给numpy.random.choice(),例如

numpy.random.choice(numpy.arange(1, 7), p=[0.1, 0.05, 0.05, 0.2, 0.4, 0.2])

如果您使用的是 Python 3.6 或更高版本,则可以random.choices()从标准库中使用——请参阅答案。

从 Python 3.6 开始,Python 的标准库中有一个解决方案,即random.choices.

示例用法:让我们设置与 OP 问题中的匹配的总体和权重:

>>> from random import choices
>>> population = [1, 2, 3, 4, 5, 6]
>>> weights = [0.1, 0.05, 0.05, 0.2, 0.4, 0.2]

现在choices(population, weights)生成一个样本:

>>> choices(population, weights)
4

可选的仅关键字参数k允许一次请求多个样本。这是很有价值的,因为random.choices在生成任何样本之前,每次调用它时都必须做一些准备工作;通过一次生成许多样本,我们只需要做一次准备工作。在这里,我们生成一百万个样本,并用于collections.Counter检查我们得到的分布是否与我们给出的权重大致匹配。

>>> million_samples = choices(population, weights, k=10**6)
>>> from collections import Counter
>>> Counter(million_samples)
Counter({5: 399616, 6: 200387, 4: 200117, 1: 99636, 3: 50219, 2: 50025})
2022-06-30