微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

scipy.stats.rv_continuous 分布与差距:支持问题?

如何解决scipy.stats.rv_continuous 分布与差距:支持问题?

我需要几个带有间隙的连续分布来拟合一些数据,并为此目的对 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,h):   return s0,s1
    
    def _pdf(self,x,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'

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

解决方法

错误很简单,当 x 是一个 numpy 数组时,您不能执行 s0 <= x <= l0(试试看!)。相反,使用按位和 : (s0 <= x) & (x <= l0) 。或者,如果您喜欢更详细的内容,请使用 np.logical_and

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

,

基于@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,h):   return s0,s1
    
    def _pdf(self,x,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]))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。