Python 用numpy绘制随机元素
我有一个元素概率数组,比如说Python 用numpy绘制随机元素,python,arrays,numpy,cumsum,Python,Arrays,Numpy,Cumsum,我有一个元素概率数组,比如说[0.1,0.2,0.5,0.2]。该数组的总和为1.0 使用普通Python或numpy,我希望绘制与其概率成比例的元素:第一个元素大约占10%的时间,第二个20%,第三个50%的时间,等等。“draw”应该返回所绘制元素的索引 我想到了这个: def draw(probs): cumsum = numpy.cumsum(probs / sum(probs)) # sum up to 1.0, just in case return len(nump
[0.1,0.2,0.5,0.2]
。该数组的总和为1.0
使用普通Python或numpy,我希望绘制与其概率成比例的元素:第一个元素大约占10%的时间,第二个20%,第三个50%的时间,等等。“draw”应该返回所绘制元素的索引
我想到了这个:
def draw(probs):
cumsum = numpy.cumsum(probs / sum(probs)) # sum up to 1.0, just in case
return len(numpy.where(numpy.random.rand() >= cumsum)[0])
这是可行的,但太复杂了,一定有更好的办法。谢谢
import numpy as np
def random_pick(choices, probs):
'''
>>> a = ['Hit', 'Out']
>>> b = [.3, .7]
>>> random_pick(a,b)
'''
cutoffs = np.cumsum(probs)
idx = cutoffs.searchsorted(np.random.uniform(0, cutoffs[-1]))
return choices[idx]
工作原理:
In [22]: import numpy as np
In [23]: probs = [0.1, 0.2, 0.5, 0.2]
计算累积总和:
In [24]: cutoffs = np.cumsum(probs)
In [25]: cutoffs
Out[25]: array([ 0.1, 0.3, 0.8, 1. ])
计算半开区间内均匀分布的随机数[0,截止值[-1])
:
用于查找将随机数插入到截止值中的索引
:
In [27]: cutoffs.searchsorted(0.9723114393023948)
Out[27]: 3
Return
choices[idx]
,其中idx
是索引。我从未使用过numpy,但我假设下面的代码(仅限python)与您在一行中完成的功能相同。我将它放在这里,以防您需要
看起来很像c-ish,所以很抱歉不是很像蟒蛇
你的总重量是1
def draw(probs)
r = random.randrange(weight_total)
running_total = 0
for i, p in enumerate(probs)
running_total += p
if running_total > r:
return i
使用
应该做到这一点。使用
numpy.random.multinomial
-最有效的您希望从分类分布中取样,该分布未在numpy中实现。但是,该分布是分布的泛化,可用于此目的
>>> import numpy as np
>>>
>>> def sampleCategory(p):
... return np.flatnonzero( np.random.multinomial(1,p,1) )[0]
...
>>> sampleCategory( [0.1,0.5,0.4] )
1
import bisect
import random
import numpy
def draw(probs):
cumsum=numpy.cumsum(probs/sum(probs))
return bisect.bisect_left(cumsum, numpy.random.rand())
>>> import numpy as np
>>>
>>> def sampleCategory(p):
... return np.flatnonzero( np.random.multinomial(1,p,1) )[0]
...
>>> sampleCategory( [0.1,0.5,0.4] )
1