【问题标题】:scipy.stats.rv_continuous distribution with gap: problems with support?scipy.stats.rv_continuous 分布有差距:支持问题?
【发布时间】:2021-07-20 02:09:09
【问题描述】:

我需要几个带有间隙的连续分布来拟合一些数据,并为此目的对scipy.stats.rv_continuous 进行子类化。下面是一个带有间隙的均匀分布的示例。在s0l 之间以及hs1 之间的分布是平坦的。

from scipy.stats import *

class gapF_gen(rv_continuous):
    ''' Class for a flat distribution with a gap in it
    s0, s1: bounds of support
    l, h: gap
    s0 < l < h < s1
    '''
    def _argcheck(self, s0, s1, l, h):  return (s0 < l < h < s1)
        
    def _get_support(self, s0, s1, l, h):   return s0, s1
    
    def _pdf(self, x, s0, s1, l, h):
        if (s0 <= x <= l) or (h <= x <= s1): return 1 / (s1 - h + l - s0)   
        else: return 0

gapF = gapF_gen(name='gapF')

bf = gapF(s0=-2.6, s1=4.77, l=-1.3, h=3.5)
print(bf.pdf(-2.8))  # OK
print(bf.pdf([-23.8, 3.8, 2.6, 6.9, 77.9])) # Not OK

我定义了_pdf 来检查值是否为零。这在将标量值传递给自动生成的pdf 时有效,但是当列表传递给pdf 时,由于范围检查,事情不起作用:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

另一方面,如果我重命名我的函数以覆盖```pdf`,那么对于标量我会得到错误:

TypeError: _parse_args() got an unexpected keyword argument 's0'

有什么建议可以解决这个问题吗?

【问题讨论】:

    标签: python inheritance scipy


    【解决方案1】:

    错误只是你不能在 x 是一个 numpy 数组的情况下执行s0 &lt;= x &lt;= l0(试试吧!)。相反,使用按位和:(s0 &lt;= x) &amp; (x &lt;= l0) 。或者,如果您喜欢更详细一点,请使用np.logical_and

    顺便说一句,你不应该覆盖pdf。子类只实现带下划线的方法:_pdf、_cdf 等。

    【讨论】:

    • 感谢@ev-br 的回复,但您的建议对我不起作用,唉。这是一个对我来说失败的更简单的例子: def test(x, y): return 1 if (x & y) else 0 print(test(1, 1)) print(test(np.array([1,1 ]), np.array([1,0])))
    • 当然不是:np.array([True, False]) &amp; np.array([True, True]) 计算结果为array([ True, False]) --- 它是一个数组,所以它不能在python if 中使用。使用 np.allnp.any 进行数组 -> 标量缩减,使用 np.where 进行元素决策。
    【解决方案2】:

    基于@ev-bre 的提示,以下工作:

    from scipy.stats import *
    
    class gapF_gen(rv_continuous):
        ''' Class for a flat distribution with a gap in it
        s0, s1: bounds of support
        l, h: gap
        s0 < l < h < s1
        '''
        def _argcheck(self, s0, s1, l, h):  return (s0 < l < h < s1)
            
        def _get_support(self, s0, s1, l, h):   return s0, s1
        
        def _pdf(self, x, s0, s1, l, h):
            return np.where(((s0 <= x) & (x <= l)) | ((h <= x) & (x <= s1)), 1 / (s1 - h + l - s0), 0)
    
    gapF = gapF_gen(name='gapF')
    
    bf = gapF(s0=-2.2, s1=4.77, l=-1.3, h=3.5)
    print(bf.pdf(-2.8))
    print(bf.pdf([-23.8, 3.8, 2.6, 6.9, 77.9, -2.1]))
    

    【讨论】:

      猜你喜欢
      • 2014-09-22
      • 1970-01-01
      • 1970-01-01
      • 2016-07-17
      • 2011-03-13
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      • 1970-01-01
      相关资源
      最近更新 更多