我正在尝试创建一个DataFrame的子类,它使用很少的属性和方法扩展它。除了默认构造函数之外,还有很少其他像下面的那个从SQL表初始化DataFrame然后添加一些属性(我简化它并留下一个虚拟只是为了演示问题)。所以一旦我得到了最初的df,我就通过df.__class__ = Cls
语句将它“转换”给我的班级。这对我来说似乎有点受欢迎,但是在这个问题上阅读了很少的帖子(例如Reclassing an instance in Python)这是一个有效的方法,而且似乎大部分时间都在工作。但问题是当我使用父类的方法(在这种情况下为DataFrame.append)时返回对象的新实例:sdf2 = sdf1.append(item)
- 生成的sdf2类是DataFrame而不是SubDataFrame,因此print('sdf2: ', sdf2.name)
失败,因为'DataFrame'没有属性'name'...底线,天真尝试使用标准DataFrame方法,我的对象已损坏...我可以通过编写(虚拟)来解决它在我的子类中附加'方法,但在这种情况下我需要为许多方法执行它,如果我不能使用继承的方法在子类中没有任何意义(我可以将DataFrame定义为我的类的成员变量)。
我想应该有这种子分类的最佳实践,只是不知道它。非常感谢任何帮助。
谢谢!
阿迪
import pandas as pd
import pandas.io.sql as pdsql
class SubDataFrame(pd.DataFrame):
@classmethod
def create(Cls):
# df = pdsql.read_sql(db_query, db_connection)
d = {'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.]}
df = pd.DataFrame(d, index=['a', 'b', 'c', 'd'])
df.__class__ = Cls
df.name = 'Test Obj'
return df
if __name__ == "__main__":
sdf1 = SubDataFrame.create()
print('sdf1: ', sdf1.__class__) # prints sdf1: <class '__main__.SubDataFrame'>"
print('sdf1: ', sdf1.name) # prints "sdf1: Test Obj"
item = sdf1.iloc[0].copy()
sdf2 = sdf1.append(item)
print('sdf2: ', sdf2.__class__) # prints: "sdf2: <class 'pandas.core.frame.DataFrame'>"
print('sdf2: ', sdf2.name) # exception: "AttributeError: 'DataFrame' object has no attribute 'name'"
pass
尝试使用@BrenB建议的super()进行测试。我阅读了参考文献(关于未绑定的超类classmethod),但仍然无法使其工作......这些是我的测试:
import pandas as pd
import pandas.io.sql as pdsql
class SubDataFrame(pd.DataFrame):
@classmethod
def create_reset_class(Cls):
d = {'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.]}
df = pd.DataFrame(d, index=['a', 'b', 'c', 'd'])
df.__class__ = Cls
df.name = 'Test Obj'
return df
@classmethod
def create_using_super(Cls):
d = {'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.]}
df = super(SubDataFrame, Cls).__init__(d, index=['a', 'b', 'c', 'd'])
df.name = 'Test Obj'
return df
def __init__(self):
d = {'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.]}
df = super(SubDataFrame, self).__init__(d, index=['a', 'b', 'c', 'd'])
df.name = 'Test Obj'
return df
if __name__ == "__main__":
sdf3 = SubDataFrame.create_using_super()
sdf4 = SubDataFrame()
sdf1 = SubDataFrame.create_reset_class()
print('sdf1: ', sdf1.__class__)
print('sdf1: ', sdf1.name)
item = sdf1.iloc[0].copy()
sdf2 = sdf1.append(item)
print('sdf2: ', sdf2.__class__)
print('sdf2: ', sdf2.name)
pass
请注意,对于我的SubDataFrame,我有一个默认的__init__
构造函数,create()
是我的(非默认)构造函数,它是一个类方法,而在其中我调用pandas.DataFrame()
这是标准绑定构造函数,期望自己而不是Cls。所以我尝试了两个选项:
一个。 df = super(SubDataFrame, Cls).__init__(d, index=['a', 'b', 'c', 'd'])
在文件“C:\ Python34 \ lib \ site-packages \ pandas \ core \ frame.py”中生成错误AttributeError,第208行:'dict'对象没有属性'_init_dict'
湾使用标准绑定构造函数__init__
不会生成任何错误,但df将返回为None(来自df = super(SubDataFrame, self).__init__(d, index=['a', 'b', 'c', 'd'])
我是否错误地使用了super()?这是一只熊猫虫吗?还有其他想法吗? 谢谢!