我有一本大字典。键是对象,值是给定对象在我的数据中出现的频率。
我想从字典中随机选择一个对象,但是要选择具有较高对应值的对象。
到目前为止,我已经可以通过将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}
如您所见,分布符合字典中描述的频率。
我的问题是,在生产代码中,我有成千上万的词典,每个词典包含数千个对象。字典的长度是可变的。我当前的方法效率很低而且很慢。有没有更好的办法?我不介意使用其他结构来存储数据。
答案 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})