第一种最笨方法:
import random weight_data={'a': 10, 'b': 15, 'c': 50} def random_weight(weight_data): all_data = [] for v, w in weight_data.items(): temp = [] for i in range(w): temp.append(v) all_data.extend(temp) n = random.randint(0,len(all_data)-1) return all_data[n]
第二种:Python带权重随机数的简单实现
思路:
该方法是常用的带权重随机数生成方法,思路是先将权重值求和total,在0与权重和total之间获得一个随机数rd,遍历权重字典,累加其权重值weight_sum,当rd小于或等于weight_sum时,返回当前的权重key值,示例代码如下:
import random weight_data={'a': 10, 'c': 50} def random_weight(weight_data): _total = sum(weight_data.values()) # 权重求和 _random = random.uniform(0, _total) # 在0与权重和之前获取一个随机数 _curr_sum = 0 _ret = None try: _keys = weight_data.iterkeys() # 使用Python2.x中的iterkeys except AttributeError: _keys = weight_data.keys() # 使用Python3.x中的keys for _k in _keys: _curr_sum += data[_k] # 在遍历中,累加当前权重值 if _random <= _curr_sum: # 当随机数<=当前权重和时,返回权重key _ret = _k break return _ret
类似简写方法(只适用于分值在小于1):
import random weight_data={'a': 0.1, 'b': 0.15, 'c': 0.} def random_weight(weight_data): rand_val = random.random() total = 0 for k, v in dct.items(): total += v if rand_val <= total: return k
第三种:使用numpy(强烈建议使用)
import numpy as np weight_data={'a': 10, 'c': 50} random_key=np.random.choice(weight_data.keys(), 1, weight_data.values())[0]
第四种:如果不想使用numpy,
from random import random from itertools import takewhile weight_data={'a': 10, 'c': 50} def accumulate(iterator): """返回元素的累积总和。. accumulate([1, 2, 3, 4, 5]) --> 1 3 6 10 15""" current = 0 for value in iterator: current += value yield current def weightedChoice(weights, objects): """从对象返回随机项,根据权重值大小 (which must sum to 1).""" limit = random() return objects[sum(takewhile(bool, (value < limit for value in accumulate(weights))))]
第五种:仅仅支持python3.6以后版本:
import random weight_data={'a': 10, 'c': 50} random.choices(weight_data.keys(), weight_data.values*(, k=10)
参考文章:
https://blog.51cto.com/techvincent/1784327
https://stackoverflow.com/questions/3679694/a-weighted-version-of-random-choice