SciPy:从PMF生成自定义随机变量

时间:2014-04-24 18:11:36

标签: python numpy scipy

我试图在Python中根据某种丑陋的分布生成随机变量。我有一个PMF的明确表达,但它涉及一些产品,这使得获取和反转CDF令人不愉快(参见下面的PMF显式形式的代码)。

本质上,我试图通过其PMF在Python中定义一个随机变量,然后使用内置代码完成从分发中抽样的艰苦工作。如果RV的支持是有限的,我知道如何做到这一点,但这里的支持是无穷无尽的。

我目前按照@ askewchan的建议尝试运行的代码如下:

import scipy as sp
import numpy as np

class x_gen(sp.stats.rv_discrete):
    def _pmf(self,k,param):
        num = np.arange(1+param, k+param, 1)
        denom = np.arange(3+2*param, k+3+2*param, 1)

        p = (2+param)*(np.prod(num)/np.prod(denom))

        return p

pa_limit = limitrv_gen()
print pa_limit.rvs(alpha,n=1)

但是,这会在运行时返回错误:

File "limiting_sim.py", line 42, in _pmf
    num = np.arange(1+param, k+param, 1)
TypeError: only length-1 arrays can be converted to Python scalars

基本上,似乎np.arange()列表在def _pmf()函数内部不起作用。我不知道为什么。任何人都可以在这里启发我/和/或指出修复?

编辑1:通过askewchan清除了一些问题,上面反映的修改。

编辑2: askewchan使用阶乘函数建议了一个有趣的近似值,但我正在寻找更精确的解决方案,例如我试图与之合作的解决方案。 np.arange。

1 个答案:

答案 0 :(得分:2)

您应该能够像这样继承rv_discrete

class mydist_gen(rv_discrete):
    def _pmf(self, n, param):
        return yourpmf(n, param)

然后您可以使用以下命令创建分发实例:

mydist = mydist_gen()

用以下代码生成样本:

mydist.rvs(param, size=1000)

或者您可以使用以下命令创建冻结分发对象:

mydistp = mydist(param)

最后用:

生成样本
mydistp.rvs(1000)

通过您的示例,这应该有效,因为factorial会自动广播。但是,它足够大alpha可能会失败:

import scipy as sp
import numpy as np
from scipy.misc import factorial

class limitrv_gen(sp.stats.rv_discrete):
    def _pmf(self, k, alpha):
        #num = np.prod(np.arange(1+alpha, k+alpha))
        num = factorial(k+alpha-1) / factorial(alpha)
        #denom = np.prod(np.arange(3+2*alpha, k+3+2*alpha))
        denom = factorial(k + 2 + 2*alpha) / factorial(2 + 2*alpha)

        return (2+alpha) * num / denom

pa_limit = limitrv_gen()
alpha = 100
pa_limit.rvs(alpha, size=10)