前言
它看起来像是几个stackoverflow问题的复制品,但我的情况(可能)有点独特。在
我的情况
我有一本字典。键是一个字符串,而值是一个整数。在
我希望python脚本随机选择N键数。在
该值表示被选中的可能性。密钥的值越高,随机选择密钥的几率就越高。
我的解决方案
因此,我利用其他一些StackOverflow帖子和互联网的强大功能,设法用加权随机来解决这个问题。在
DICT_VAR= {'best':308281009, 'good':7066325, 'meh':26884, 'bad':71, 'terrible':16, 'never':0}
list_var = []
for i in DICT_VAR.keys():
list_var.extend([i]*DICT_VAR[i])
print random.sample(list_var, 2) # get 2 random choice I suppose
问题(捕获)
您可能注意到,字典中的值可以是难以置信的大(它可以无限大),也可以小到0(零是最小的,没有负数)。在
运行这个代码(数字稍大一点)导致我的计算机冻结和无响应,直到我硬重置它。在
我的问题
我该如何处理这种情况?有没有其他的随机选择的方法适合我的情况,因为加权随机是当前情况下最糟糕的解决方案。在
我在这里假设一个值
0
意味着永远不应该选择这个键,这些键可能会在示例中重复(在字典中是不相关的),在这种情况下,我们可以使用第三方模块numpy。这是在python3.6.4中测试的代码,但是我修改了它,使它在python2.7中运行,但是我不能用这种方式测试它。在然后
sample
将示例保存为一个键字符串列表。注意,键'best'
的权重比其他权重大得多,因此样本几乎总是['best', 'best']
。在解释我的代码:首先将字典的键(字符串)和值(权重)拆分成单独的列表。然后把权重改为概率,权重越大,概率越大,权重越小,概率越小。然后使用numpy的
choice
函数选择一个使用概率作为权重的密钥样本。结果是一个numpy数组,但是您似乎想要一个标准的Python列表,因此最后一行将键的示例转换为标准列表。在当然,有一个相当短的例程可以用标准Python编写,因此我们可以避免使用numpy。但很可能会慢一些。在
你的例程慢的原因是它建立了一个大的列表,每个键重复其值给定的次数,然后以均匀的概率选择一个样本。对于示例数据,这意味着要构建一个比可用RAM大得多的庞大列表,这需要花费大量时间。Numpy的choice例程可以直接处理非均匀随机分布,而无需构建另一个列表。在
在Py3.6中,这是标准库的一部分,带有
random.choices()
:或者更神秘的是:
^{pr2}$相关问题 更多 >
编程相关推荐