继承scipy.stats.rv_continuous实现自定义分布报_parse_args参数缺失错误
问题解决办法
核心错误原因有3个:
- 自定义
rv_continuous子类需要显式声明shapes属性,告知scipy你自定义的分布有哪些形状参数,scipy不会自动从方法签名里提取参数。 - 你的
_argcheck方法参数漏了mu,参数数量和实际形状参数不匹配;同时调用truncnorm时的参数名写错,均值参数是loc不是ac。 - 你调用
truncgauss()创建冻结分布实例时没有传入必填的4个参数,触发了参数解析错误。如果不需要冻结分布,可以直接调用truncgauss.rvs()传入参数即可。
修改后的完整代码如下:
from scipy.stats import rv_continuous import scipy.stats class truncgauss_gen(rv_continuous): ''' a and b are bounds of true support mu is mean sig is std dev ''' # 显式声明形状参数 shapes = "a, b, mu, sig" def _argcheck(self, a, b, mu, sig): # 补上mu参数,mu无额外校验规则 return (a < b) and (sig > 0) def _get_support(self, a, b, mu, sig): return a, b def _pdf(self, x, a, b, mu, sig): # 修正参数名ac为loc return scipy.stats.truncnorm.pdf(x, (a - mu) / sig, (b - mu) / sig, loc=mu, scale=sig) def _rvs(self, a, b, mu, sig, size=None, random_state=None): # 修正参数名ac为loc,补上random_state参数避免警告 return scipy.stats.truncnorm.rvs((a - mu) / sig, (b - mu) / sig, loc=mu, scale=sig, size=size, random_state=random_state) truncgauss = truncgauss_gen(name='truncgauss', momtype=1) if __name__ == '__main__': print(scipy.__version__) # 用法1:直接调用rvs不创建冻结实例 dat = truncgauss.rvs(a=-5.1, b=10.07, mu=2.3, sig=1.2, size=10) print(dat) # 用法2:创建冻结实例,参数传入构造函数 tg = truncgauss(a=-5.1, b=10.07, mu=2.3, sig=1.2) dat2 = tg.rvs(size=10) print(dat2)
补充说明:
- 原测试代码还漏了
sig参数的传入,修改后的代码补充了该参数赋值,可直接运行。 - 低版本scipy的
_rvs方法需要显式接收random_state参数传递给底层实现,避免生成随机数时的警告。
内容的提问来源于stack exchange,提问作者Mister Mak
相关产品推荐
相关产品推荐

