继承pandas DataFrame的类中self=修改无效的原因及正确方法
继承pandas DataFrame后修改self不生效的原因及解决方法
问题场景
自定义类myDataFrame继承自pandas的DataFrame,在类方法中执行self = self[["Name", "Number"]]试图重排列顺序,但调用方法后原对象并未被修改。
示例代码
import pandas class myDataFrame(pandas.DataFrame): def __init__(self, adict): super().__init__(adict) def df_reorder_columns(self): self = self[["Name", "Number"]] # 此行赋值不生效 my_data = {'Number': [1, 2], 'Name': ['Adam', 'Abel']} test_myDataFrame = myDataFrame(my_data) print(test_myDataFrame) test_myDataFrame.df_reorder_columns() print(test_myDataFrame)
运行输出
Number Name 0 1 Adam 1 2 Abel Number Name 0 1 Adam 1 2 Abel
原因解析
在Python中,self是方法内部的局部变量,指向当前实例对象。当执行self = self[["Name", "Number"]]时,你只是把局部变量self重新指向了一个新的DataFrame对象(pandas的索引操作默认返回新对象,而非修改原对象),但这不会改变外部原来的实例对象的引用。简单说:方法里的self只是个"指针副本",改这个副本的指向,不会影响外面原来的对象。
正确修改方式
要修改原对象,需要直接操作实例的内部数据结构,或使用pandas提供的原地修改操作,以下是两种可靠方法:
方法1:直接修改实例的columns属性
通过重新赋值self.columns调整列顺序,实现原地修改:
import pandas class myDataFrame(pandas.DataFrame): def __init__(self, adict): super().__init__(adict) def df_reorder_columns(self): # 直接修改列顺序,原地更新原对象 self.columns = ["Name", "Number"] my_data = {'Number': [1, 2], 'Name': ['Adam', 'Abel']} test_myDataFrame = myDataFrame(my_data) print("修改前:") print(test_myDataFrame) test_myDataFrame.df_reorder_columns() print("修改后:") print(test_myDataFrame)
方法2:使用reindex方法原地修改
利用pandas的reindex方法指定列顺序,结合inplace=True实现原地修改:
import pandas class myDataFrame(pandas.DataFrame): def __init__(self, adict): super().__init__(adict) def df_reorder_columns(self): # 用reindex原地重排列 self.reindex(columns=["Name", "Number"], inplace=True) my_data = {'Number': [1, 2], 'Name': ['Adam', 'Abel']} test_myDataFrame = myDataFrame(my_data) print("修改前:") print(test_myDataFrame) test_myDataFrame.df_reorder_columns() print("修改后:") print(test_myDataFrame)
修改后的运行输出
两种方法都会得到如下结果:
修改前: Number Name 0 1 Adam 1 2 Abel 修改后: Name Number 0 Adam 1 1 Abel 2
内容的提问来源于stack exchange,提问作者CarlosE
相关产品推荐
相关产品推荐

