在Python中使用给定概率密度函数生成随机数

6

我希望能够生成一个整数随机数,其概率分布函数作为一个列表给出。 例如,如果 pdf=[3,2,1],那么我想要 rndWDist(pdf) 返回 0、1 和 2,它们的概率分别为 3/6、2/6 和 1/6。 因为在 random 模块中找不到相应的函数,所以我自己编写了该功能。

def randintWDist(pdf):
    cdf=[]
    for x in pdf:
        if cdf:
            cdf.append(cdf[-1]+x)
        else:
            cdf.append(x)
    a=random.randint(1,cdf[-1])
    i=0
    while cdf[i]<a:
        i=i+1
    return i

有没有更简单的方法来达到相同的结果?

3个回答

6
这是一个重复的问题:根据给定的(数字)分布生成随机数。正如那里的第一个答案建议的那样,您可能想使用scipy.stats.rv_discrete。您可以像这样使用它:
from scipy.stats import rv_discrete
numbers = (1,2,3)
distribution = (1./6, 2./6, 3./6)
random_variable = rv_discrete(values=(numbers,distribution))
random_variable.rvs(size=10)

这将返回一个包含10个随机值的numpy数组。

1
给定您的输入格式,您可以这样做:

def randint_with_dist(pdf):
    choices = []
    for index, value in enumerate(pdf):
        choices.extend(index for _ in range(value))
    return random.choice(choices)

每次传递相同的 pdf 时都会使用相同的列表,您可以考虑缓存列表以提高效率(牺牲空间):

def randint_with_dist(pdf, choices={}):
    pdf = tuple(pdf)
    if pdf not in choices:
        choices[pdf] = []
        for index, value in enumerate(pdf):
            choices[pdf].extend(index for _ in range(value))
    return random.choice(choices[pdf])

1
使用numpy(1.7版本或更高版本),您也可以使用np.random.choice
In [27]: import numpy as np

In [28]: distribution = (1./6, 2./6, 3./6)

In [29]: np.random.choice(np.arange(len(distribution)), p=distribution)
Out[29]: 0

In [30]: np.random.choice(np.arange(len(distribution)), p=distribution, size=10)
Out[30]: array([2, 1, 1, 2, 2, 0, 1, 0, 1, 0])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接