如何子类scipy.stats.norm?

时间:2013-07-31 16:01:10

标签: python inheritance scipy

我想继承scipy.stats.norm,以便我可以拥有具有附加功能的冻结分布实例(即具有特定均值/方差)。 但是,我无法超越构建实例的第一步。

编辑:这是一个交互式会话的记录,可以说明我的问题(我的袖子里没有任何东西)

In [1]: import scipy.stats

In [2]: class A(scipy.stats.norm):
   ...:     def __init__(self):
   ...:         super( A, self).__init__()
   ...:         
   ...:         
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/Dave/src/python2.7/density_estimation/<ipython console> in <module>()

/usr/lib64/python2.7/site-packages/scipy/stats/distributions.pyc in __init__(self, momtype, a, b, xa, xb, xtol, badvalue, name, longname, shapes, extradoc)
    958 
    959         if longname is None:
--> 960             if name[0] in ['aeiouAEIOU']:
    961                 hstr = "An "
    962             else:

TypeError: Error when calling the metaclass bases
    'NoneType' object is not subscriptable

我可以看到scipy.stats正在做某种奇怪的事情norm是某事物的某个特定实例(sometype?),但它不是正常的类定义,所以我看不到如何为它调用构造函数。

编辑#2:scipy版本可能是相关的。

In [19]: scipy.__version__
Out[19]: '0.9.0'

2 个答案:

答案 0 :(得分:2)

scipy.stats.norm不是一个班级。它是scipy.stats.norm_gen的一个实例。调用norm(*args, **kwds)将返回rv_frozen的{​​{1}}实例以及您提供的参数。如果你想要一种新的冻结分布,子类norm来添加你的方法,并用rv_frozen和参数进行实例化。不要担心继承norm

答案 1 :(得分:1)

我倾向于认为错误存在于你没有展示的地方。班级本身应该没有问题。事实上:

class GaussianKernel(scipy.stats.norm):
def __init__(self, mu, sigma):
    super( GaussianKernel, self).__init__(loc=mu, scale=sigma)

G = GaussianKernel(5,.2)
G.mean() # returns 5
G.std() # returns .2

然而,当使用scipy时,应该调用:

from scipy.stats import norm

而不是:

import scipy.stats.norm

希望这会有所帮助......

编辑:

您所指的奇怪行为似乎是类'规范'也可以用作函数。他们在docs

中称之为rv_frozen对象

有一个关于子类化here的段落可能会有所帮助。 rv_continuous模块不能用作函数,也许这是正确的方法!