我想从每个字都知道的机会的清单中选取一个字句,例如:
具有可证明性的产品
Orange 0.10 Apple 0.05 Mango 0.15 etc
如何以最佳方式执行? 我将从实际清单中提取最多100个物项,而其百分比并不等于100%,以计入实际较少发生机会的项目。 我很想从我存放这一数据的CSV那里来这样做。 这不是一项关键的任务。
感谢你就如何最好地开展工作提出任何建议。
我想从每个字都知道的机会的清单中选取一个字句,例如:
具有可证明性的产品
Orange 0.10 Apple 0.05 Mango 0.15 etc
如何以最佳方式执行? 我将从实际清单中提取最多100个物项,而其百分比并不等于100%,以计入实际较少发生机会的项目。 我很想从我存放这一数据的CSV那里来这样做。 这不是一项关键的任务。
感谢你就如何最好地开展工作提出任何建议。
如果您将每个项目分配到与其概率成正比的一定范围,在零到幅度之间随机抽取数量,并找到与该项目相匹配的项目,则你可以选择加权。 下面的班级确实是:
from random import random
class WeightedChoice(object):
def __init__(self, weights):
"""Pick items with weighted probabilities.
weights
a sequence of tuples of item and it s weight.
"""
self._total_weight = 0.
self._item_levels = []
for item, weight in weights:
self._total_weight += weight
self._item_levels.append((self._total_weight, item))
def pick(self):
pick = self._total_weight * random()
for level, item in self._item_levels:
if level >= pick:
return item
然后,你可以将CSV文档装上csv
。 模块并将其输入<代码> 重量级:
import csv
weighed_items = [(item,float(weight)) for item,weight in csv.reader(open( file.csv ))]
picker = WeightedChoice(weighed_items)
print(picker.pick())
您想从 多边分发。 假设你有两份项目清单和概率清单,以及可负担的数额(如果不是,仅增加一些违约价值以弥补额外损失):
def choose(items,chances):
import random
p = chances[0]
x = random.random()
i = 0
while x > p :
i = i + 1
p = p + chances[i]
return items[i]
lst = [ ( Orange , 0.10), ( Apple , 0.05), ( Mango , 0.15), ( etc , 0.69) ]
x = 0.0
lst2 = []
for fruit, chance in lst:
tup = (x, fruit)
lst2.append(tup)
x += chance
tup = (x, None)
lst2.append(tup)
import random
def pick_one(lst2):
if lst2[0][1] is None:
raise ValueError, "no valid values to choose"
while True:
r = random.random()
for x, fruit in reversed(lst2):
if x <= r:
if fruit is None:
break # try again with a different random value
else:
return fruit
pick_one(lst2)
这形成了一个新的清单,其 as价值代表了选择水果的各种价值;然后, pick(一)冲倒了清单,看着“斜”的价值;=目前的随机价值。 我们把“哨兵”价值列入清单的末尾;如果数值不超过1.0,就有可能产生一种随机价值,而这种价值与任何数值相匹配,并将与所投的价值相匹配,然后予以拒绝。 随机(0.0、1.0)将随机数值归为[0、1.0],因此,确定最终与清单中的内容相匹配。
这里的一点是,你应该能够拥有一个价值,拥有0.000001的匹配机会,而且实际上应该与这一频率相匹配;另一种解决办法是,如果你提出清单,重复并公正地使用随机选择的项目,则需要一份清单,其中列出100万件。
lst = [ ( Orange , 0.10), ( Apple , 0.05), ( Mango , 0.15), ( etc , 0.69) ]
x = 0.0
lst2 = []
for fruit, chance in lst:
low = x
high = x + chance
tup = (low, high, fruit)
lst2.append(tup)
x += chance
if x > 1.0:
raise ValueError, "chances add up to more than 100%"
low = x
high = 1.0
tup = (low, high, None)
lst2.append(tup)
import random
def pick_one(lst2):
if lst2[0][2] is None:
raise ValueError, "no valid values to choose"
while True:
r = random.random()
for low, high, fruit in lst2:
if low <= r < high:
if fruit is None:
break # try again with a different random value
else:
return fruit
pick_one(lst2)
# test it 10,000 times
d = {}
for i in xrange(10000):
x = pick_one(lst2)
if x in d:
d[x] += 1
else:
d[x] = 1
我认为这更清楚。 我们不是把幅度作为ending升值的简单方法,而是保持幅度。 由于我们正在测试范围,我们只能走到最快的2个数值上来;无需使用<代码>reversed(<>/code>)。
from numpy.random import multinomial
import numpy as np
def pickone(dist):
return np.where(multinomial(1, dist) == 1)[0][0]
if __name__ == __main__ :
lst = [ ( Orange , 0.10), ( Apple , 0.05), ( Mango , 0.15), ( etc , 0.70) ]
dist = [p[1] for p in lst]
N = 10000
draws = np.array([pickone(dist) for i in range(N)], dtype=int)
hist = np.histogram(draws, bins=[i for i in range(len(dist)+1)])[0]
for i in range(len(lst)):
print(f {lst[i]} {hist[i]/N} )
一种解决办法是使诱发的概率正常化,然后按价值重复每个要素(例如,一份列有2个 Orange虫、1个 Apple果、3个芒斯的清单)。 很难做到(<>随机进口选择代码<>)。 如果这不可行,可尝试使用。
import random
d= { orange : 0.10, mango : 0.15, apple : 0.05}
weightedArray = []
for k in d:
weightedArray+=[k]*int(d[k]*100)
random.choice(weightedArray)
<><><>>>>
这基本上是Brian上文所述的。