从 Python 3.6 开始,您可以使用内置的 random.choices() 而不必使用 Numpy。
那么,如果我们想从您的字典中采样(替换)25 个键,其中的值是被采样的权重/概率,我们可以简单地写:
import random
random.choices(list(my_dict.keys()), weights=my_dict.values(), k=25)
这会输出一个采样键列表:
['c', 'b', 'c', 'b', 'b', 'c', 'c', 'c', 'b', 'c', 'b', 'c', 'b', 'c', 'c', 'c', 'c', 'c', 'a', 'b']
如果您只需要一个键,请将 k 设置为 1 并从 random.choices 返回的列表中提取单个元素:
random.choices(list(my_dict.keys()), weights=my_dict.values(), k=1)[0]
(如果您不将 my_dict.keys() 转换为列表,您将收到关于它如何不可下标的 TypeError。)
这是来自docs的相关sn-p:
random.choices(population, weights=None, *, cum_weights=None, k=1)
返回一个 k 大小的元素列表,该列表是从具有替换的总体中选择的。如果人口为空,则引发 IndexError。
如果指定了权重序列,则根据相对权重进行选择。或者,如果给出了 cum_weights 序列,则根据累积权重进行选择(可能使用 itertools.accumulate() 计算)。例如,相对权重 [10, 5, 30, 5] 等价于累积权重 [10, 15, 45, 50]。在内部,相对权重会在进行选择之前转换为累积权重,因此提供累积权重可以节省工作量。
如果既没有指定权重也没有指定 cum_weights,则以相等的概率进行选择。如果提供了权重序列,则它必须与总体序列的长度相同。同时指定权重和 cum_weights 是 TypeError。
权重或 cum_weights 可以使用与 random() 返回的浮点值互操作的任何数字类型(包括整数、浮点数和分数,但不包括小数)。权重假定为非负数。
对于给定的种子,具有相同权重的choices() 函数通常会产生与重复调用choice() 不同的序列。 Choices() 使用的算法使用浮点算法来实现内部一致性和速度。 choice() 使用的算法默认为整数运算,重复选择,以避免舍入误差产生的小偏差。
根据https://stackoverflow.com/a/39976962/5139284 的 cmets,random.choices 对于小型阵列更快,numpy.random.choice 对于大型阵列更快。 numpy.random.choice 还提供了无需替换即可采样的选项,而没有内置的 Python 标准库函数。