2014-09-03 83 views
3

我想用列表給出一個概率分佈函數的整數隨機數。 例如,如果pdf = [3,2,1],那麼我喜歡 rndWDist(pdf) 返回0,1和2,概率爲3/6,2/6和1/6。 我寫了自己的函數,因爲我無法在隨機模塊中找到它。用Python給出的PDF的隨機數

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 

是否有更短的方法來達到相同的結果?

+0

的[生成與給定的(數值)分佈的隨機數]可能重複(http://stackoverflow.com/questions/4265988 /產生隨機號碼上帶有一個給出的數值分配) – juankysmith 2014-09-04 14:26:01

回答

2

這是一個重複的問題:Generate random numbers with a given (numerical) distribution

作爲第一個答案有建議,你可能想給我們e 。

您可以使用它像:

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]) 
0

使用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])