合并含不同列的Pandas DataFrame:如何实现预期的合并结果
解决Pandas DataFrame合并时重复行的问题
先看你的原始数据和需求:
你有两个DataFrame:
import pandas as pd df1 = pd.DataFrame({'name':['a','b'], 'data1':[3,4]}) df2 = pd.DataFrame({'name':['a','c'], 'data2':[1,5]})
想要合并得到这样的结果:
| name | data1 | data2 |
|---|---|---|
| a | 3 | 1 |
| b | 4 | NaN |
| c | NaN | 5 |
但你当前的collect_results函数得到了重复的a行,问题出在合并键的错误指定上——你写的pd.merge(df,df_target_info, how="outer", on=["name",target])把name和当前的目标列(比如data1、data2)都当成了合并键,这就导致第二次合并时,因为两列的内容完全不匹配,a行被拆成了两行。
简化的修改方案
其实根本不需要这么复杂的循环逻辑,直接用Pandas自带的merge函数就能搞定:
df_desired = pd.merge(df1, df2, on='name', how='outer')
如果你要保留多DataFrame的函数处理逻辑
如果你的实际场景是要合并多个DataFrame(不止两个),可以修改函数,确保每次只以name作为合并键,同时简化冗余的中间步骤:
方案1:用reduce批量合并(推荐)
import pandas as pd from functools import reduce def collect_results(df_list): # 依次合并所有DataFrame,始终以name为键做outer join return reduce(lambda left, right: pd.merge(left, right, on='name', how='outer'), df_list) # 调用示例 df1 = pd.DataFrame({'name':['a','b'], 'data1':[3,4]}) df2 = pd.DataFrame({'name':['a','c'], 'data2':[1,5]}) df_desired = collect_results([df1, df2]) print(df_desired)
方案2:修改你原来的循环逻辑
import pandas as pd def collect_results(target_list, df_list): # 初始化df为第一个DataFrame的副本,避免空表的麻烦 df = df_list[0].copy() # 从第二个DataFrame开始循环合并 for df_target in df_list[1:]: # 只以name作为合并键,outer join保留所有行 df = pd.merge(df, df_target, on='name', how='outer') return df # 调用示例 df1 = pd.DataFrame({'name':['a','b'], 'data1':[3,4]}) df2 = pd.DataFrame({'name':['a','c'], 'data2':[1,5]}) df_desired = collect_results(['data1','data2'], [df1, df2]) print(df_desired)
关键修改点说明
- 去掉了合并键里的
target列,只保留name作为唯一匹配依据,这样同名的行就会正确合并成一行 - 删掉了不必要的中间DataFrame创建(比如
df_target_info,因为传入的df_list里已经有完整的name和目标列数据) - 初始化时直接用第一个DataFrame,避免空表合并带来的额外问题
内容的提问来源于stack exchange,提问作者user11128
相关产品推荐
相关产品推荐

