如何合并Pandas中非交叉的DataFrame块?
解决非交叉DataFrame块合并的NaN与列重叠问题
问题背景
现有多组非交叉的DataFrame块:
- df_11、df_12:共享索引
'1'、'2',列无重叠 - df_21、df_22:共享索引
'3'、'4',列无重叠
需要合并为包含所有列、无NaN值的完整DataFrame。使用循环join会产生NaN值,还可能出现列名重叠问题,直接收集列和索引的方式不够优雅,需更合适的方案。
示例数据
import pandas as pd df_11 = pd.DataFrame([[1,1], [1,1]], index=['1', '2'], columns=['col1', 'col2']) df_12 = pd.DataFrame([[2,2], [2,2]], index=['1', '2'], columns=['col3', 'col4']) df_21 = pd.DataFrame([[3,3], [3,3]], index=['3', '4'], columns=['col1', 'col2']) df_22 = pd.DataFrame([[4,4], [4,4]], index=['3', '4'], columns=['col3', 'col4'])
预期结果
col1 col2 col3 col4 1 1 1 2 2 2 1 1 2 2 3 3 3 4 4 4 3 3 4 4
问题代码(循环join)
df = pd.DataFrame() for ele in [df_11, df_12, df_21, df_22]: df = df.join(ele, how='outer')
该方法会产生NaN值,且重复join同列名时会自动添加后缀,不符合需求。
优雅解决方案
方案1:分组合并后再纵向拼接
先将同索引组的DataFrame横向合并(补全同索引的所有列),再将各组结果纵向拼接:
# 合并同索引组的DF group1 = pd.concat([df_11, df_12], axis=1) group2 = pd.concat([df_21, df_22], axis=1) # 拼接两组结果 final_df = pd.concat([group1, group2])
方案2:全局concat后按索引去重补值
利用pd.concat先将所有DF堆叠,再按索引分组取有效值(因非交叉,每组索引下的列只会有一个非NaN值):
# 堆叠所有DF stacked = pd.concat([df_11, df_12, df_21, df_22]) # 按索引分组,取每组各列的第一个有效值 final_df = stacked.groupby(stacked.index).first()
方案3:用combine_first批量合并
先合并同列的DF,再用combine_first补全索引:
# 合并同列的DF col1_col2 = pd.concat([df_11, df_21]) col3_col4 = pd.concat([df_12, df_22]) # 补全所有列 final_df = col1_col2.combine_first(col3_col4)
以上三种方案均可得到无NaN、列完整的目标DataFrame,代码简洁且逻辑清晰。
内容的提问来源于stack exchange,提问作者user6703592
相关产品推荐
相关产品推荐

