为scipy.stats.rv_continuous添加方法遇rv_frozen属性错误问题
问题原因
- scipy中直接调用
uniform()、gamma(a)这类构造返回的是rv_frozen类的实例,该类独立于rv_continuous,仅通过组合关系关联分布参数,因此给rv_continuous新增的方法不会同步到rv_frozen实例 - 原方法的参数定义仅支持固定传参,无法兼容非冻结分布需要传入形状参数、loc、scale的场景
可行解决方案
步骤1:导入依赖并定义兼容所有场景的通用方法
需要同时处理冻结/非冻结分布的参数差异,支持位置/关键字两种方式传入总计数nu:
from scipy.stats import rv_continuous, uniform, gamma from scipy.stats._distn_infrastructure import rv_frozen def cntsCumul(self, x, *args, **kwargs): # 提取总计数nu:优先取关键字参数,否则取最后一个位置参数 if "nu" in kwargs: nu = kwargs.pop("nu") else: nu = args[-1] args = args[:-1] return nu * self.cdf(x, *args, **kwargs)
步骤2:同时给两类对象新增方法
# 给非冻结分布类加方法 rv_continuous.cntsCumul = cntsCumul # 给冻结分布类加方法 rv_frozen.cntsCumul = cntsCumul
测试验证
你的原有测试用例可全部正常运行:
x = [-0.76, 1.2, 5.67] a = 2 # 非冻结uniform调用 for xx in x: print(uniform.cdf(xx)) # 原有逻辑正常 print(uniform.cntsCumul(xx, 3)) # 新增方法正常 # 冻结uniform调用 rv1 = uniform() for xx in x: print(rv1.cdf(xx)) # 原有逻辑正常 print(rv1.cntsCumul(xx, 3)) # 新增方法正常 # 非冻结gamma调用 for xx in x: print(gamma.cdf(xx, a)) # 原有逻辑正常 print(gamma.cntsCumul(xx, a, 3)) # 新增方法正常 # 也支持关键字传nu:gamma.cntsCumul(xx, a, nu=3) # 冻结gamma调用 rv2 = gamma(a) for xx in x: print(rv2.cdf(xx)) # 原有逻辑正常 print(rv2.cntsCumul(xx, 3)) # 新增方法正常
额外说明
该实现完全对齐scipy原有cdf的传参规则,支持传入loc、scale等可选参数,例如:
# 指定偏移和缩放参数的调用示例 print(gamma.cntsCumul(1.2, a=2, loc=0.5, scale=1.5, nu=10))
内容的提问来源于stack exchange,提问作者Mister Mak
相关产品推荐
相关产品推荐

