生成具有 python 中加权概率的随机数

Generating random numbers with weighted probabilities in python

给定一个正整数数组a,目标是根据数组中的权重生成 5 个随机数。

例如:

a = [2,3,4,4,4,4,4,6,7,8,9]

在这种情况下数字4出现了5次,在这种情况下数字4出现的概率应该是5/11

数字不应重复。

您可能正在寻找 numpy.random.multinomial 例如 np.random.multinomial(1, [1/6.]*6, size=1) 是掷一次公平的骰子。 获得结果后,您可以根据需要更新概率向量(必须总和为 1)。例如 numpy.random.multinomial(1, [1/2., 1/2., 0., 0., 0., 0.], size=1).

最简单的解决方案(可能也是最低效的)如下:

import random
def get_randoms(n, a):
    a = a[:]
    r = []
    for i in range(n):
        r.append(random.choice(a))
        a = [y for y in a if y != r[-1]]
    return r

print get_randoms(5, [2,3,4,4,4,4,4,4,5,6,7,8,9,4,9,2,3,6,3,1])

输出可能类似于

[8, 2, 3, 6, 9]

给定 a,一个正整数数组,您首先需要计算每个整数的频率。例如,使用 bincount:

>>> a = [2,3,4,4,4,4,4,4,5,6,7,8,9,4,9,2,3,6,3,1]
>>> b = np.bincount(a)

b告诉你a中每个整数出现的频率。因此,相应的权重集是数组 b/len(a)。使用具有这些权重的 np.random.choicereplace=False 应该可以满足您的需求:

>>> np.random.choice(np.arange(len(b)), 5, p=b/len(a), replace=False)
array([5, 9, 4, 3, 8])
>>> np.random.choice(np.arange(len(b)), 5, p=b/len(a), replace=False)
array([7, 4, 6, 9, 1])
>>> np.random.choice(np.arange(len(b)), 5, p=b/len(a), replace=False)
array([3, 7, 4, 9, 6])

如果您不只使用正整数,或者如果您使用大的正整数,@user2357112 在下面的评论中指出 np.unique 提供了另一种解决方案。在这里你会写:

>>> choices, counts = np.unique(a, return_counts=True)
>>> np.random.choice(choices, 5, p=counts/len(a), replace=False)
array([9, 8, 2, 4, 5])