向 scipy.stats.rv_continuous 添加方法,rv_frozen 出现问题

Adding methods to scipy.stats.rv_continuous, problems with rv_frozen

我想为 scipy.stats.rv_continuous 中的所有分布添加一个方法。该方法将 return 累积计数,即额外参数 nu(总计数)与现有 cdf 函数的乘积。我尝试将新方法添加到 rv_continuous class,如下所示:

from scipy.stats import rv_continuous, uniform, gamma

def cntsCumul(self, x, nu): return nu * self.cdf(x)

rv_continuous.cntsCumul = cntsCumul

x = [-0.76, 1.2, 5.67]

for xx in x: print(uniform.cdf(xx)) # OK
for xx in x: print(uniform.cntsCumul(xx, 3)) # Not OK
    
rv1 = uniform()    
for xx in x: print(rv1.cdf(xx)) # OK
for xx in x: print(rv1.cntsCumul(xx, 3)) # Not OK
    
a = 2

for xx in x: print(gamma.cdf(xx, a)) # OK
for xx in x: print(gamma.cntsCumul(xx, a, 3)) # OK

rv2 = gamma(a)
for xx in x: print(rv2.cdf(xx)) # OK
for xx in x: print(rv2.cntsCumul(xx, 3)) # Not OK

但出现以下错误:

---> 14 for xx in x: print(rv1.cntsCumul(xx, 3)) # Not OK
     15 
     16 a = 2

AttributeError: 'rv_frozen' object has no attribute 'cntsCumul'

不确定如何处理 rv_frozen。有什么建议么?另外,不确定参数会不会出问题。

您看到的直接问题是 rv2.cntsCumul(xx, 3) 创建了一个所谓的冻结分布,它具有形状并且 loc/scale 是固定的 --- 这样,例如norm(loc=0, scale=2).pdf(x)等同于norm.pdf(x, loc=0, scale=2)等,源码中见rv_continuous.__call__等。 现在,冻结分布(rv_frozen 实例)创建底层 rv_continuous 子类的新实例(存储为 rv_frozen 实例的 self.dist 属性),并且那个人不知道你的猴子补丁。

另请注意,您所做的并没有考虑形状参数:例如gamma 的形状为 a,因此签名为 scipy.stats.gamma.pdf(x, a, loc, scale)。 loc 和 scale 有默认值,但 shapes 没有。

附带说明一下,就像我在评论中所说的那样,委婉地说,您所做的有点不标准。 当然非常容易出错。 如果你需要多个发行版,只需将它们的 _gen 类 子类化,或者如果你真的需要的话,对实例进行猴子修补。