[英]Random number with given PDF in Python
I want to generate an integer random number with a probability distribution function given as a list. 我想生成一个整数随机数,其概率分布函数作为列表给出。 For example if pdf=[3,2,1] then I like rndWDist(pdf) to return 0,1, and 2, with probabilities of 3/6, 2/6, and 1/6. 例如,如果pdf = [3,2,1],那么我喜欢rndWDist(pdf)返回0,1和2,概率为3 / 6,2 / 6和1/6。 I wrote my own function for that since I couldn't find it in the random module. 我为自己编写了自己的函数,因为我在随机模块中找不到它。
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
Is there any shorter method to achieve the same result? 有没有更短的方法来实现相同的结果?
This is a duplicate question: Generate random numbers with a given (numerical) distribution 这是一个重复的问题: 生成具有给定(数字)分布的随机数
As the first answer there suggest, you might want to use scipy.stats.rv_discrete
. 作为第一个答案,您可能希望使用scipy.stats.rv_discrete
。
You might use it like that: 您可以这样使用它:
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)
This returns a numpy array with 10 random values. 这将返回一个包含10个随机值的numpy数组。
Given the format of your input, you could do: 根据您的输入格式,您可以:
def randint_with_dist(pdf):
choices = []
for index, value in enumerate(pdf):
choices.extend(index for _ in range(value))
return random.choice(choices)
As the same list will be used every time the same pdf
is passed, you could consider caching the list for greater efficiency (at the cost of space): 由于每次传递相同的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])
Using numpy (version 1.7 or newer), you could also use np.random.choice : 使用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])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.