0

我有一个元素列表,例如L = [A, B, C]. 例如,每个元素都有一个相关的分数S = [5, 1, 4]

我想根据它在 S 中的分数从 L 中选择一个元素,只需生成一种累积概率分布,其中每个元素L[i]对应一个与(0,1]成比例的区间S[i]。然后,在 (0,1] 中绘制的随机数映射到所选元素。

对于前面给出的示例,我们可以S通过对 进行归一化来将 的分数表示为概率,然后5+1+4我们SS = [0.5, 0.1, 0.4]将 的元素映射L到区间,这样:

B is mapped to (0, 0.1]
C is mapped to (0.1, 0.1+0.4]
A is mapped to (0.1+0.4, 0.5+0.5]

r现在,如果我在 (0,1] (eg ) 中生成一个随机数r = random.random(),它将映射到相应的元素。例如,如果r = 0.03我们知道元素是 B。例如,如果r = 0.73我们知道元素是 A .. .

python中是否有一种简单的方法可以在元素和区间之间进行这种映射?

我知道我可以numpy.cumsum用来生成 SS 的累积和,但是如何将元素映射到从这个累积和获得的区间?

4

2 回答 2

2

假设我理解正确,我会推荐一个dict

def branchFinder(L, S, r):
    S, L = map(list, zip(*sorted(zip(S, L))))
    SS = [0.] + map(lambda x: x/10., S)

    probs = {}
    for i in range(len(L)):
        probs[L[i]] = (sum(SS[:i+1]), SS[i+1] + sum(SS[:i+1]))        

    for key, value in probs.iteritems():
        if value[0] < r <= value[1]:
             return key
于 2014-01-29T17:35:59.633 回答
2

您可以使用Counter

from collections import Counter
counts = Counter(dict(zip(L, S)))

给予,例如:

Counter({'A': 5, 'C': 4, 'B': 1})

然后使用此答案从中随机选择:

from random import randrange
from itertools import islice

index = randrange(sum(counts.values()))
next(islice(counts.elements(), index, None))

或者只是从列表中选择(也许更清楚正在发生的事情,但对于大列表效率较低):

from random import choice

choice(list(counts.elements()))

这并不能回答您的确切问题(生成概率),但希望能得到您需要的结果(根据分数随机选择)。

于 2014-01-29T17:38:54.393 回答