Numpy中的加权选择不以准确的输入概率返回列表

时间:2018-09-13 01:40:32

标签: python numpy

我有一个对象['P1','P2','P3']的列表,其权重为[0.8,0.1,0.1]。

我发现numpy选项将权重作为输入,但是我看不到输出列表与输入概率完全匹配

代码:

draw = [choice(['P1','P2','P3'],p=[0.8,0.1,0.1]) for _ in range(10)]
from collections import Counter
print(Counter(draw))

我希望绘图始终包含P1的8个实例,P2的1个和P3的1个实例。

但是我发现使用上述代码时,每次运行都会有所不同。

示例输出:

Run 1:
Counter({'P1': 7, 'P2': 2, 'P3': 1})

Run 2:
Counter({'P1': 10})

Run 3:
Counter({'P1': 9, 'P2': 1})

我错过了什么吗?或者这是预期的输出?

2 个答案:

答案 0 :(得分:0)

numpy.random.choice中的documentation告诉您参数p是与每个条目相关联的概率。如果未给出,则假定概率统一。

一致概率表示选择任何一项的概率相等。 但这并不意味着结果的数量总是与概率成比例

示例:抛硬币时,获得正面的概率等于获得正面的概率。但是,当我扔10次时,我会总是得到5个正面和5个反面吗?不。

toss=[np.random.choice(["head","tail"]) for _ in range(10)]
print(Counter(toss)) #Counter({'head': 7, 'tail': 3})

类似地,您只提到获得P1的概率为0.8,但这并不意味着您随机选择10次后总会看到8个P1,这仅意味着获得它的可能性大大高于其他人。

编辑

要获得所需的功能,可以编写一个复制列表项的函数。给定概率(p = 0.8)和ht总项目数(n = 10),应复制的次数为p*n

def MyDist(elements,weights,num):
    a=[]
    for i in range(len(elements)):
        a+=[elements[i]]*int(weights[i]*num)
    return a

MyDist(['P1','P2','P3'],[0.8,0.1,0.1],10)
#['P1', 'P1', 'P1', 'P1', 'P1', 'P1', 'P1', 'P1', 'P2', 'P3']

答案 1 :(得分:0)

使用np.repeatnp.random.shuffle

def draw(elements, counts):
    out =  np.repeat(elements, counts)
    np.random.shuffle(out)
    return out

draw(['P1','P2', 'P3'], [8,1,1])
Out: 
array(['P1', 'P3', 'P2', 'P1', 'P1', 'P1', 'P1', 'P1', 'P1', 'P1'], 
      dtype='<U2')