Python 将列表元素映射到区间以创建累积概率分布

Python 将列表元素映射到区间以创建累积概率分布,python,distribution,probability,cdf,Python,Distribution,Probability,Cdf,我有一个元素列表,例如L=[a,B,C]。每个元素都有一个相关的分数,例如S=[5,1,4] 我想根据L在S中的分数从L中选择一个元素,只需生成一种累积概率分布,其中每个元素L[I]对应于(0,1]中与S[I]成比例的区间。然后,(0,1]中绘制的随机数映射到所选元素 对于前面给出的示例,我们可以通过对5+1+4进行归一化,将S的分数表示为概率,因此我们得到SS=[0.5,0.1,0.4],并将L的元素映射到区间,这样: B is mapped to (0, 0.1] C is mapped t

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

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

对于前面给出的示例,我们可以通过对
5+1+4
进行归一化,将
S
的分数表示为概率,因此我们得到
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]
现在,如果我在(0,1)中生成一个随机数
r
(例如
r=random.random()
),它将映射到相应的元素。例如,如果
r=0.03
我们知道元素是B。例如,如果
r=0.73
我们知道元素是a

python中有没有一种简单的方法来实现元素和区间之间的映射


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

假设我正确理解您的意思,我建议使用
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
def分支指示器(左、南、右): S、 L=map(列表,zip(*已排序(zip(S,L))) SS=[0.]+映射(λx:x/10.,S) probs={} 对于范围内的i(len(L)): probs[L[i]=(总和(SS[:i+1]),SS[i+1]+总和(SS[:i+1])) 对于键,probs.iteritems()中的值:
如果值[0]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
def分支指示器(左、南、右): S、 L=map(列表,zip(*已排序(zip(S,L))) SS=[0.]+映射(λx:x/10.,S) probs={} 对于范围内的i(len(L)): probs[L[i]=(总和(SS[:i+1]),SS[i+1]+总和(SS[:i+1])) 对于键,probs.iteritems()中的值:
如果值[0]计数器

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 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))
或者从列表中选择(可能更清楚发生了什么,但在大列表中效率较低):


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

只是澄清一下:您想要一个列表,以便在生成随机数时,返回列表中相应的元素?让我检查一下我是否理解正确。您想要从均匀分布生成cdf定义的任意离散随机变量?@JoelCornett不,这不是我想要做的。我只想创建一个基于元素列表和分数/概率的CDF。这样我们就可以根据该CDF随机选择一个元素。只是澄清一下:你想要一个列表,这样当生成一个随机数时,列表中相应的元素就会返回?让我检查一下我是否理解正确。你想要生成任意离散的随机变量吗由cdf从均匀分布中定义的变量?@JoelCornett不,这不是我想要做的。我只想根据元素列表和分数/概率创建一个cdf。这样我们就可以根据该cdf随机选择一个元素。如果值是有序的(就像cdf中的值一样)没有必要做第一个小于比较。@JoelCornett值可能会被排序到字典中,但不一定会从字典中出来!我不确定您指的是哪个值。如果您指的是
value
的值,那么您必须同时做这两个比较,因为它们位于一个
dict
中,该dict的顺序不受其属性的影响nature@jonrsharpe:这意味着
dict
可能不是存储CDF的最佳方式;)这是可以的,使用以下方法修复:
对于probs.iteritems()中的键,值。
。谢谢。如果值是按顺序排列的,(就像它们在CDF中一样)没有必要做第一个小于比较。@JoelCornett值可能会被排序到字典中,但不一定会从字典中出来!我不确定您指的是哪个值。如果您指的是
value
的值,那么您必须同时做这两个比较,因为它们位于一个
dict
中,该dict的顺序不受其属性的影响nature@jonrsharpe:这意味着
dict
可能不是存储CDF的最佳方式;)这是可以的,使用以下方法修复:
对于键,probs.iteritems()中的值。
。谢谢。