随机模拟中经常出现的一个问题是计算几个事件中的哪一个发生。这通常通过具有每个事件的概率来完成。然后生成一个随机数,然后迭代可能的事件,直到找到它们的概率总和超过随机数的位置。
以下是执行我想要的代码,但我正在采用更好的方法。
import random
def getEvent(eventProbabilities,probability):
S = 0
for key in eventProbabilities.keys():
S += eventProbabilities[key]
if S>= probability: #key is the event to happen.
break
return key
x = {'event1' : 0.1 , 'event2' : 0.2 , 'event3' : 0.2 , 'event4' : 0.4, 'event5' : 0.1} #values sum to 1.
p = random.random() #random number between 0 and 1.
event = getEvent(x,p)
print p, event
我觉得必须有一种更紧凑的方式来定义getEvent - 可能使用takewhile
- 但我找不到它。
我追求最高效率,因为我认为这是我的代码将花费大部分时间的地方。
有没有办法通过itertools(或其他方式)提高效率?
编辑后面添加评论我们是否关注迭代顺序。
您会注意到密钥将按某种顺序处理。该顺序与随机数p无关。让我们考虑一下它按照我列出的顺序处理它们的情况。如果p<=0.1
那么它将返回event1
因此有10%的可能性它是event1。如果0.1<p<0.3
它将返回event2
(因此概率为20%)。现在我们考虑一个不同的顺序。说它按相反的顺序排列。在这种情况下,如果0.9<p
我们将获得event1
(10%),而如果0.7<p<=0.9
我们获得event2
(再次为20%)。因此,无论顺序如何,每个事件的概率都是相同的。
我只想选择1个事件,我希望以相应的概率选择该事件。
答案 0 :(得分:3)
如果我理解正确,您只需要从给定概率的列表中选择一个元素。为什么不使用numpy
?
>>> x = {'event1': 0.1 , 'event2': 0.2 , 'event3': 0.2 , 'event4': 0.4,
'event5': 0.1}
>>> events, p = zip(*x.items())
>>> np.random.choice(events, p=p, replace=False)
'event4'