random.choice 的加权版本

新手上路,请多包涵

我需要编写一个加权版本的 random.choice(列表中的每个元素都有不同的被选中概率)。这就是我想出的:

 def weightedChoice(choices):
    """Like random.choice, but each element can have a different chance of
    being selected.

    choices can be any iterable containing iterables with two items each.
    Technically, they can have more than two items, the rest will just be
    ignored.  The first item is the thing being chosen, the second item is
    its weight.  The weights can be any numeric values, what matters is the
    relative differences between them.
    """
    space = {}
    current = 0
    for choice, weight in choices:
        if weight > 0:
            space[current] = choice
            current += weight
    rand = random.uniform(0, current)
    for key in sorted(space.keys() + [current]):
        if rand < key:
            return choice
        choice = space[key]
    return None

这个功能对我来说似乎过于复杂,而且很难看。我希望这里的每个人都可以提供一些改进建议或替代方法。效率对我来说不如代码整洁和可读性重要。

原文由 Colin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 559
2 个回答

从 1.7.0 版本开始,NumPy 有一个支持概率分布的 choice 函数。

 from numpy.random import choice
draw = choice(list_of_candidates, number_of_items_to_pick,
              p=probability_distribution)

请注意, probability_distribution 是与 list_of_candidates 顺序相同的序列。您还可以使用关键字 replace=False 来更改行为,以便不替换绘制的项目。

原文由 Ronan Paixão 发布,翻译遵循 CC BY-SA 4.0 许可协议

由于 Python 3.6 有一个方法 choices 来自 random 模块。

 In [1]: import random

In [2]: random.choices(
...:     population=[['a','b'], ['b','a'], ['c','b']],
...:     weights=[0.2, 0.2, 0.6],
...:     k=10
...: )

Out[2]:
[['c', 'b'],
 ['c', 'b'],
 ['b', 'a'],
 ['c', 'b'],
 ['c', 'b'],
 ['b', 'a'],
 ['c', 'b'],
 ['b', 'a'],
 ['c', 'b'],
 ['c', 'b']]

请注意, random.choices 将根据 文档 进行替换 采样:

返回一个 k 大小的元素列表,这些元素是从带有替换的人口中选择的。

回答完整性注意事项:

当抽样单位从有限总体中抽取并返回到该总体时,在记录其特征之后,在抽取下一个单位之前,抽样被称为“有替代”。它基本上意味着每个元素可以被选择多次。

如果您需要在不更换的情况下进行采样,那么正如 @ronan-paixão 的精彩回答 所述,您可以使用 numpy.choice ,其 replace 参数控制此类行为。

原文由 vishes_shell 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏