我已经定义了一个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有很多,我不想为每个人手动执行此操作。
我认为可能有一种方法可以应用一些装饰器包装每个父方法,但我不知道如何做到这一点,或者它是否是正确的方法。
这个问题对于子类继承返回父实例的方法的所有情况都是通用的。
有谁知道如何解决这个问题?
答案 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
我不知道这是否解决了一般问题,其中子类继承了返回父实例的方法。但是,我不确定可以是一般解决方案,因为返回的实例可以任意构造。