Python 以指定概率获取元素


这是Python cookbook的示例

复制代码
1 def random_pick(some_list,probabilities): 2   x=random.uniform(0,1) 3   cumulative_probability=0.0 4   for item,item_probability in zip(some_list,probabilities): 5     cumulative_probability+=item_probability 6     if x < cumulative_probability: break 7   return item
复制代码

什么意思呢?

random.uniform(0,1)->生成0.0到1.0之间的伪随机数,之后循环元素及其概率,计算累积概率.

如:random_pick([1,2,3,4],[0.1,0.2,0.3,0.4])

当x处于0.0到0.1之间,则输出1

当x处于0.1到0.3之间,则输出2

...........

在这里可以做个测试:

复制代码
def test_random(nu): a=[1,2,3,4] b=[0.1,0.2,0.3,0.4] re=dict(zip(a,[0]*4)) for x in xrange(nu): result=random_pick(a,b) re[result]+=1 for v,value in re.iteritems(): re[v]=float(value)/nu return re print test_random(100000)
复制代码

结果:

{ 1 : 0.099250000000000005 , 2 : 0.19950999999999999 , 3 : 0.30030000000000001 , 4 : 0.40094000000000002 }

另一个有点类似的任务是根据一个非负整数的序列所定义的权重进行随机撷取---基于机会,而不是概率

复制代码
import random def random_picks(sequence,relative_odds):   table=[z for x,y in zip(sequence,relative_odds) for z in [x]*y]   while True:     yield random.choice(table) x=random_picks('ciao',[1,1,3,2]) import itertools print ''.join(itertools.islice(x,8))
复制代码

输出:

oooocaco

这里我们也做个测试:

复制代码
result=''.join(itertools.islice(x,100000)) c=result.count('c') i=result.count('i') a=result.count('a') o=result.count('o') min=min(c,i,a,o) print float(c)/min,':',float(i)/min,':',float(a)/min,':',float(o)/min
复制代码

输出:

1.0 : 1.0210748156 : 3.00316122234 : 2.00070249385

这两个例子有什么区别呢?

第一个例子要求som_list的长度和probabilities的长度一致,以及所有元素的概率相加为1.0

而第二个例子需要非负整数.


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM