函数内修改pandas DataFrame内容外部不生效问题排查
问题原因
你对Python参数传递的理解存在部分偏差:
- 函数形参
data在刚传入时,确实和外部的train_x_categorical指向同一个DataFrame对象,因此函数内执行data.drop(feature, axis=1, inplace=True)时,会直接修改外部原对象,这部分符合引用传递的表现。 - 问题出在
data = pd.concat([data, dummies], axis=1)这行代码:pd.concat()不会修改原有对象,而是返回一个全新创建的DataFrame。这行赋值执行后,函数内部的局部变量data就不再指向最初传入的外部对象,而是指向了这个新生成的DataFrame。你在循环内打印的data.columns,实际是这个局部新对象的列信息,和外部的train_x_categorical没有关联。 - 最终效果就是:原对象上只执行了删除原始分类列的操作,拼接哑变量的步骤完全作用在临时生成的新对象上,函数执行结束后临时对象被回收,主流程自然看不到独热编码的效果。
修复方案
提供两种可直接落地的实现方式:
方案1:返回处理后的新对象(推荐)
这是pandas数据处理的通用最佳实践,避免inplace操作带来的隐蔽引用问题,逻辑更可控。
修改类方法:
def applyOneHotEncoding(self, data): processed_data = data.copy() for feature in self._featuresToBeOneHotEncoded: dummies = pd.get_dummies(processed_data[feature]) dummies.drop(dummies.columns[-1], axis=1, inplace=True) processed_data = processed_data.drop(feature, axis=1) processed_data = pd.concat([processed_data, dummies], axis=1) print(processed_data.columns) return processed_data
主流程调用时接收返回值即可:
train_x_categorical = dataCleaner.applyOneHotEncoding(train_x_categorical) train_x_categorical.head()
方案2:原地修改原对象
如果不想修改主流程的调用逻辑,可以调整方法内的实现,始终保持对原对象的引用,不做局部变量重定向:
def applyOneHotEncoding(self, data): for feature in self._featuresToBeOneHotEncoded: dummies = pd.get_dummies(data[feature]) dummies.drop(dummies.columns[-1],axis=1,inplace=True) data.drop(feature, axis=1, inplace=True) # 直接给原对象追加列,不重新赋值data变量 for col_name in dummies.columns: data[col_name] = dummies[col_name] print(data.columns)
注意该方案如果哑变量的列名和原数据已有列名重名,会直接覆盖原有列数据。
内容的提问来源于stack exchange,提问作者fabianod
相关产品推荐
相关产品推荐

