合并pandas DataFrame时如何合并非键的同名公共列
解决方案
以下两种实现方式均无需循环,可满足你的需求:
方法1:合并后合并同名列再筛选
在merge时指定后缀区分不同来源的3列,合并后直接将多列3按优先级合并,最后只保留需要的三列即可:
import pandas as pd # 两次左连接,用后缀标记不同表的3列 merge_temp = pd.merge(df, df1, how='left', on=['1','2'], suffixes=('', '_df1')) merge_temp = pd.merge(merge_temp, df2, how='left', on=['1','2'], suffixes=('', '_df2')) # 合并三个3列,优先级可自行调整,下方示例优先级为 df.3 > df1.3 > df2.3 # pandas 1.3.0以上版本可直接用coalesce逻辑: merge_temp['3'] = merge_temp['3'].combine_first(merge_temp['3_df1']).combine_first(merge_temp['3_df2']) # 也可以用反向填充的写法兼容低版本: # merge_temp['3'] = merge_temp[['3', '3_df1', '3_df2']].bfill(axis=1).iloc[:, 0] # 仅保留目标列 res = merge_temp[['1','2','3']]
该方法完全保留左连接的逻辑,可灵活调整不同表3列的取值优先级。
方法2:先拼接再分组聚合
如果不需要严格限制仅保留df的键组合,可直接拼接三个表后按键分组取非空值,逻辑更简洁:
# 纵向拼接三个表,拼接顺序决定取值优先级,排在前面的表优先级更高 all_df = pd.concat([df, df1, df2], ignore_index=True) # 按键分组,取每组3列的第一个非空值 res = all_df.groupby(['1','2'], as_index=False)['3'].first()
如果需要严格对齐左连接的键范围,只需要最后加一步左连接过滤即可:
res = df[['1','2']].merge(res, on=['1','2'], how='left')
内容的提问来源于stack exchange,提问作者QuestionMan
相关产品推荐
相关产品推荐

