Python中继承pd.DataFrame的类__init__方法内fillna不生效原因排查
问题原因分析
你遇到的这个问题,核心在于pandas的fillna()方法默认行为是返回一个填充后的新DataFrame对象,而不是直接修改原对象。
在你的__init__方法里,当你调用self.fillna(0)(默认inplace=False)时,它只是生成了一个新的填充后DataFrame,但你没有把这个新对象和当前类实例绑定,所以原来的实例数据并没有被修改。而你在__init__里打印时,大概率是直接打印了fillna()返回的新对象,所以看起来生效了,但实际类实例本身还是原来的未填充状态,外部调用自然看不到变化。
解决方案
有两种靠谱的方式可以解决这个问题:
方式一:用inplace=True强制原地修改
把fillna的参数设置为inplace=True,这样它会直接修改当前DataFrame的内容,不需要返回新对象:
import pandas as pd class MyDataFrame(pd.DataFrame): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 原地填充缺失值,直接修改当前实例 self.fillna(0, inplace=True) print(self) # 这里打印的是修改后的实例本身 # 测试验证 df = MyDataFrame({'a': [1, None], 'b': [None, 2]}) print(df) # 现在命令行调用也能看到填充后的结果
方式二:将填充后的新对象赋值给实例底层数据
如果你不想用inplace=True(有些复杂场景下原地修改可能引发副作用),可以把fillna返回的新对象的底层数据替换到当前实例中:
import pandas as pd class MyDataFrame(pd.DataFrame): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 获取填充后的新DataFrame,替换当前实例的底层数据 filled_df = self.fillna(0) self._data = filled_df._data print(self) # 测试验证 df = MyDataFrame({'a': [1, None], 'b': [None, 2]}) print(df)
补充:为什么__init__里打印看似生效?
如果你之前的代码是这样写的:
print(self.fillna(0)) # 这里打印的是fillna返回的新对象,不是self本身
那你看到的填充结果只是临时生成的新对象,self其实还是原来的未填充状态,这就是外部调用时失效的原因。
内容的提问来源于stack exchange,提问作者Kaladin
相关产品推荐
相关产品推荐

