带有“percentage”的Python随机选择

2024-10-16 20:43:04 发布

您现在位置:Python中文网/ 问答频道 /正文

前言

它看起来像是几个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(零是最小的,没有负数)。在

运行这个代码(数字稍大一点)导致我的计算机冻结和无响应,直到我硬重置它。在

我的问题

我该如何处理这种情况?有没有其他的随机选择的方法适合我的情况,因为加权随机是当前情况下最糟糕的解决方案。在


Tags: 字符串脚本字典var密钥情况整数random
2条回答

我在这里假设一个值0意味着永远不应该选择这个键,这些键可能会在示例中重复(在字典中是不相关的),在这种情况下,我们可以使用第三方模块numpy。这是在python3.6.4中测试的代码,但是我修改了它,使它在python2.7中运行,但是我不能用这种方式测试它。在

DICT_VAR= {'best':308281009, 'good':7066325, 'meh':26884, 'bad':71,
           'terrible':16, 'never':0}

import numpy as np

keys, weights = zip(*DICT_VAR.items())
probs = np.array(weights, dtype=float) / float(sum(weights))
sample_np = np.random.choice(keys, 2, p=probs)
sample = [str(val) for val in sample_np]

然后sample将示例保存为一个键字符串列表。注意,键'best'的权重比其他权重大得多,因此样本几乎总是['best', 'best']。在

解释我的代码:首先将字典的键(字符串)和值(权重)拆分成单独的列表。然后把权重改为概率,权重越大,概率越大,权重越小,概率越小。然后使用numpy的choice函数选择一个使用概率作为权重的密钥样本。结果是一个numpy数组,但是您似乎想要一个标准的Python列表,因此最后一行将键的示例转换为标准列表。在

当然,有一个相当短的例程可以用标准Python编写,因此我们可以避免使用numpy。但很可能会慢一些。在

你的例程慢的原因是它建立了一个大的列表,每个键重复其值给定的次数,然后以均匀的概率选择一个样本。对于示例数据,这意味着要构建一个比可用RAM大得多的庞大列表,这需要花费大量时间。Numpy的choice例程可以直接处理非均匀随机分布,而无需构建另一个列表。在

在Py3.6中,这是标准库的一部分,带有random.choices()

In []:
import random
random.choices(list(DICT_VAR.keys()), DICT_VAR.values(), k=2)

Out[]:
['best', 'best']

或者更神秘的是:

^{pr2}$

相关问题 更多 >