合并Pandas DataFrame时引入NaN值的问题及解决需求
解决多Pandas DataFrame合并后出现NaN或重复列的问题
核心问题根源
- 使用
concat时,若按行合并但列名不统一,会因列对齐产生NaN;若按列合并未指定正确键,会导致数据错位或重复。 - 使用
merge时,未将id+gr_code设为组合合并键,或选错合并方式(how参数),要么丢失数据,要么出现无匹配的NaN。 - 重复列多因合并后同名列未处理后缀,或重复合并同一键导致。
解决方案(附示例代码)
假设有三个预处理后的DataFrame(已执行dropna()):
import pandas as pd df1 = pd.DataFrame({ 'id': [1,2,3], 'gr_code': ['A','B','C'], 'value1': [10,20,30] }).dropna(subset=['id', 'gr_code', 'value1']) df2 = pd.DataFrame({ 'id': [1,2,4], 'gr_code': ['A','B','D'], 'value2': [100,200,400] }).dropna(subset=['id', 'gr_code', 'value2']) df3 = pd.DataFrame({ 'id': [1,3,4], 'gr_code': ['A','C','D'], 'value3': [1000,3000,4000] }).dropna(subset=['id', 'gr_code', 'value3'])
方法1:基于组合键的逐步merge
以id+gr_code作为唯一匹配键,通过how参数控制合并范围:
# 先合并前两个DataFrame merged = pd.merge(df1, df2, on=['id', 'gr_code'], how='outer') # 再合并第三个DataFrame final_df = pd.merge(merged, df3, on=['id', 'gr_code'], how='outer')
- 若需仅保留所有DataFrame都存在的
id+gr_code组合,将how='outer'改为how='inner'即可消除NaN。 - 若合并后出现重复列,添加
suffixes参数区分来源(如suffixes=('_df1', '_df2'))。
方法2:concat+groupby(适合数值列可统一命名的场景)
先统一数值列名,合并后按组合键聚合去重:
# 重命名所有数值列为同一名称 df1_renamed = df1.rename(columns={'value1': 'value'}) df2_renamed = df2.rename(columns={'value2': 'value'}) df3_renamed = df3.rename(columns={'value3': 'value'}) # 合并后按组合键取首个有效数值(或用sum/mean等聚合逻辑) final_df = pd.concat([df1_renamed, df2_renamed, df3_renamed])\ .groupby(['id', 'gr_code'])['value'].first().reset_index()
方法3:索引join(简化版合并)
将id+gr_code设为索引,通过索引快速合并:
# 设置组合索引 df1_idx = df1.set_index(['id', 'gr_code']) df2_idx = df2.set_index(['id', 'gr_code']) df3_idx = df3.set_index(['id', 'gr_code']) # 按索引合并,自动对齐组合键 final_df = df1_idx.join([df2_idx, df3_idx], how='outer').reset_index()
关键注意事项
- 确保
id和gr_code在所有DataFrame中的数据类型完全一致(如都是int或str),否则会因类型不匹配导致无法产生有效匹配。 - 执行
dropna()时,建议用subset参数指定关键列(如dropna(subset=['id', 'gr_code'])),避免误删仅数值列为NaN的有效数据行。 - 若合并后仍有NaN,大概率是存在仅在部分DataFrame中出现的
id+gr_code组合,可根据业务需求用fillna()填充(如final_df.fillna(0, inplace=True))。
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

