调用含pandas concat的DataPreparation类未返回转换后DataFrame
问题根因
拿不到处理后DataFrame的核心原因:
onehotencoder_labels方法中执行pd.concat后,会生成一个全新的DataFrame对象,你把这个新对象赋值给了实例属性self.df_train、self.df_test,这步操作直接切断了实例属性和你最初传入类的外部df变量的引用关联,外部的原始df变量不会自动同步成拼接后的新对象。- 你实例化类之后,直接查看最初传入的外部
df_train、df_test变量的内容,没有从类实例的属性上读取处理完成的结果。
另外现有代码还有两处瑕疵:一是独热编码生成新列后没有删除原始的Embarked分类列,会保留冗余字段;二是众数变量名存在拼写错误(commont应为common),不影响运行但不符合编码规范。
修复方法
- 实例化类后,不要读取外部原始df变量,直接访问类实例的
df_train、df_test属性获取处理完成的数据集。 - 补全独热编码后的冗余列删除逻辑,修正笔误。
修复后的代码和正确使用示例:
import pandas as pd class DataPreparation: def __init__( self, df_train: pd.DataFrame, df_test: pd.DataFrame ): self.df_train = df_train self.df_test = df_test self.add_embarked() def add_embarked(self): all_embarked = pd.concat([self.df_train.Embarked, self.df_test.Embarked]) most_common_value_emb = all_embarked.mode()[0] self.df_train.Embarked.fillna(most_common_value_emb, inplace=True) self.df_test.Embarked.fillna(most_common_value_emb, inplace=True) self.onehotencoder_labels("Embarked") def onehotencoder_labels(self, column: str): one_hot_encoder_train = pd.get_dummies(self.df_train[column]) one_hot_encoder_test = pd.get_dummies(self.df_test[column]) self.df_train = pd.concat([self.df_train, one_hot_encoder_train], axis=1) self.df_test = pd.concat([self.df_test, one_hot_encoder_test], axis=1) # 删除原始分类列,消除冗余 self.df_train.drop(columns=[column], inplace=True) self.df_test.drop(columns=[column], inplace=True) # 调用示例 # 此处为原始读取的训练、测试数据 # df_train = pd.read_csv("train.csv") # df_test = pd.read_csv("test.csv") processor = DataPreparation(df_train, df_test) # 从实例属性获取处理完成的数据集,不要使用原始外部变量 processed_train = processor.df_train processed_test = processor.df_test
如果你需要让传入的外部原始df变量同步所有改动(包括独热编码新增列的改动),可以修改
onehotencoder_labels的逻辑,不给实例属性重新赋值,而是直接在原df对象上新增列:def onehotencoder_labels(self, column: str): one_hot_encoder_train = pd.get_dummies(self.df_train[column]) one_hot_encoder_test = pd.get_dummies(self.df_test[column]) # 直接在原df上新增列,不生成新对象 self.df_train[one_hot_encoder_train.columns] = one_hot_encoder_train self.df_test[one_hot_encoder_test.columns] = one_hot_encoder_test self.df_train.drop(columns=[column], inplace=True) self.df_test.drop(columns=[column], inplace=True)这种写法下外部变量和实例属性始终指向同一个DataFrame对象,改动会自动同步,但通常更推荐从实例属性取处理结果的写法,避免意外修改原始数据。
内容的提问来源于stack exchange,提问作者user19504753
相关产品推荐
相关产品推荐

