如何通过匹配model_year用另一DataFrame填充缺失值?及代码排查
二手车数据缺失值填充问题排查与解决
问题背景
现有两个DataFrame:
- 在售二手车数据
df:
| model_year | engine | seats |
|---|---|---|
| A4_2022 | v4 | NaN |
| mustang_1966 | v8 | 5 |
| A4_2022 | NaN | NaN |
| defender_1988 | NaN | 8 |
model_year列存在重复值,但整行数据不重复engine、seats等字段存在缺失值
- 参考数据
df_model:
| model_year | engine | seates |
|---|---|---|
| a4_2022 | v4 | 5 |
| defender_1988 | v8 | 8 |
- 包含部分
model_year的完整字段信息
需求:遍历df,当字段缺失时,通过匹配model_year从df_model拉取对应值填充,需考虑部分model_year不在df_model中的情况。
用户尝试的循环代码未成功填充,代码如下:
for index, row in df.iterrows(): if pd.isnull(row['Seats']): model = row['model_year'] seats = df_model[df_model['model_year'] == model]['Seats'].values if len(seats) > 0: df.loc[index, 'Seats'] = seats[0]
原代码问题分析
- 大小写不匹配:
df中model_year是A4_2022(大写开头),但df_model中对应值是a4_2022(小写开头),导致匹配失败。 - 列名拼写错误:
df_model中座位列的列名是seates(多了一个e),但代码中用了Seats,无法取到对应值。 - 列名大小写不一致:
df中的列名是seats(小写),但代码中判断和赋值用了Seats(大写),会触发KeyError或无法正确识别列。
修复后的循环代码
针对上述问题修正,同时处理model_year不存在的情况:
# 统一model_year的大小写,避免匹配失败 df['model_year'] = df['model_year'].str.lower() df_model['model_year'] = df_model['model_year'].str.lower() # 修复列名拼写问题,统一列名 df_model.rename(columns={'seates': 'seats'}, inplace=True) for index, row in df.iterrows(): # 检查seats字段是否缺失 if pd.isnull(row['seats']): model = row['model_year'] # 从df_model中匹配对应值 matched = df_model[df_model['model_year'] == model] if not matched.empty: df.loc[index, 'seats'] = matched['seats'].values[0]
更高效的Pandas批量处理方案
iterrows循环效率较低,推荐用map或merge实现批量填充,适合大数据量场景:
方法1:使用map填充
# 预处理:统一大小写+修正列名 df['model_year'] = df['model_year'].str.lower() df_model['model_year'] = df_model['model_year'].str.lower() df_model.rename(columns={'seates': 'seats'}, inplace=True) # 构建model_year到seats的映射字典 seats_map = df_model.set_index('model_year')['seats'].to_dict() # 填充缺失值:仅填充原本缺失的部分 df['seats'] = df['seats'].fillna(df['model_year'].map(seats_map))
方法2:使用merge批量填充(适合多字段同时填充)
如果需要同时填充engine和seats,可以用左连接后填充:
# 预处理 df['model_year'] = df['model_year'].str.lower() df_model['model_year'] = df_model['model_year'].str.lower() df_model.rename(columns={'seates': 'seats'}, inplace=True) # 左连接参考数据 merged_df = df.merge(df_model, on='model_year', how='left', suffixes=('', '_ref')) # 填充缺失值 df['engine'] = df['engine'].fillna(merged_df['engine_ref']) df['seats'] = df['seats'].fillna(merged_df['seats_ref'])
内容的提问来源于stack exchange,提问作者Dalv32
相关产品推荐
相关产品推荐

