如何从字典中获取随机对象,并按值加权

时间:2018-10-24 20:57:17

标签: python performance dictionary random big-o

我有一本大字典。键是对象,值是给定对象在我的数据中出现的频率。

我想从字典中随机选择一个对象,但是要选择具有较高对应值的对象。

到目前为止,我已经可以通过将x个对象添加到列表中(其中x是字典中的对应值)来实现此目的。然后,我在此列表上呼叫random.choice()。像这样:

import random

myDict = { 'foo' : 10,
           'boo' : 5,
           'moo' : 3,
           'roo' : 2,
           'goo' : 1,
           'oo' : 0}

selection = []
for obj in myDict.keys():
    for n in range(myDict[obj]):
        selection.append(obj)

为确保此功能正常运行,我已在列表上运行random.choice() 10000次并保存了结果。这是我得到的4个结果。

{'foo': 4841, 'boo': 2397, 'moo': 1391, 'roo': 907, 'goo': 464, 'oo': 0}
{'foo': 4771, 'boo': 2410, 'moo': 1435, 'roo': 917, 'goo': 467, 'oo': 0}
{'foo': 4815, 'boo': 2340, 'moo': 1431, 'roo': 953, 'goo': 461, 'oo': 0}
{'foo': 4718, 'boo': 2443, 'moo': 1404, 'roo': 947, 'goo': 488, 'oo': 0}

如您所见,分布符合字典中描述的频率。

我的问题是,在生产代码中,我有成千上万的词典,每个词典包含数千个对象。字典的长度是可变的。我当前的方法效率很低而且很慢。有没有更好的办法?我不介意使用其他结构来存储数据。

1 个答案:

答案 0 :(得分:1)

numpy提供了一个可选的概率参数,该参数应该可以解决您的问题:

In [14]: s = sum(myDict.values())

In [15]: d2 = {k: v/float(s) for k, v in myDict.items()}

In [16]: res = np.random.choice(list(d2.keys()), 10000, p=list(d2.values()))

In [17]: from collections import Counter

In [18]: Counter(res)
Out[18]: Counter({'foo': 4723, 'moo': 1426, 'boo': 2411, 'roo': 945, 'goo': 495})