Python使用方法链接保留子类

时间:2018-02-27 17:07:09

标签: python pandas class oop inheritance

我已经定义了一个pandas Dataframe的子类。子类基本上与数据帧相同,但有其他方法可以完成专门的任务。

pandas数据帧最方便的特性之一是支持方法链接;也就是说,dataframe方法返回dataframe类的实例。

我希望能够使用这些方法,但是当我从子类中调用它们时,我得到了父类的实例。

import pandas as pd

class MySpecialDF(pd.DataFrame):
    def sqrt(self, colname):
        return self[colname]**2.0

df = MySpecialDF({'a':[1,2,3], 'b':[4,5,6]})
df.sqrt('a') # all good!

df = df.drop('b', axis=1) # returns a regular DF
df.sqrt('a') # AttributeError: 'DataFrame' object has no attribute 'sqrt'

如何进行设置以便这些方法返回子类的实例?

我可以手动覆盖这样的单个方法:

class MySpecialDF(pd.DataFrame):
    def sqrt(self, colname):
        return self[colname]**2.0

    def drop(self, *args, **kwargs):
        return MySpecialDF(super(MySpecialDF, self).drop(*args, **kwargs))

但是Dataframes有很多,我不想为每个人手动执行此操作。

我认为可能有一种方法可以应用一些装饰器包装每个父方法,但我不知道如何做到这一点,或者它是否是正确的方法。

这个问题对于子类继承返回父实例的方法的所有情况都是通用的。

有谁知道如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

感谢@ayhan让我指向正确的方向。我跟着评论this documentation,这显示了如何在pandas中专门完成子类化。修复是:

class MySpecialDF(pd.DataFrame):

    @property
    def _constructor(self):
        return MySpecialDF

    def sqrt(self, colname):
        return self[colname]**2.0

我不知道这是否解决了一般问题,其中子类继承了返回父实例的方法。但是,我不确定可以是一般解决方案,因为返回的实例可以任意构造。