能否使用concat合并两个DataFrame并基于多列匹配去重?
基于多列匹配合并DataFrame:为什么concat不行?正确做法看这里
嗨,你的需求很明确!直接给结论:concat没法实现你要的基于多列匹配合并的效果,因为concat的核心是按行/列方向直接拼接数据,不会根据指定的键(比如name和age)去做匹配对齐。要得到你想要的合并结果,得用pandas.merge()做外连接,再简单处理缺失值就行,具体步骤如下:
第一步:先复现你的输入数据
先把你给出的df1和df2用代码创建出来,方便后续操作:
import pandas as pd # 创建df1 df1 = pd.DataFrame( { 'name': ['jack', 'ben', 'lisa'], 'age': [20, 19, 30], 'hobby': ['hockey', 'chess', 'golf'], 'married': ['yes', 'no', 'no'] } ) # 创建df2 df2 = pd.DataFrame( { 'name': ['jack', 'anna', 'dan'], 'age': [20, 34, 26], 'hobby': ['hockey', 'football', 'golf'], 'job': ['student', 'finance', 'retail'] } )
第二步:用merge做外连接匹配
我们需要用外连接(outer join),这样能保留两个DataFrame里的所有行,同时根据name和age匹配对齐相同的记录:
# 基于name和age做外连接,hobby列在两个df都有,所以用suffixes区分 merged_df = pd.merge(df1, df2, on=['name', 'age'], how='outer', suffixes=('', '_df2')) # 处理hobby列:如果df1的hobby为空,就用df2的hobby填充,然后删掉多余的列 merged_df['hobby'] = merged_df['hobby'].fillna(merged_df['hobby_df2']) merged_df.drop('hobby_df2', axis=1, inplace=True) # 把所有缺失值替换成你要的 '/' merged_df = merged_df.fillna('/') # 重置索引,和你示例的index格式一致 merged_df.reset_index(drop=True, inplace=True)
运行完这段代码后,merged_df就是你想要的结果:
| index | name | age | hobby | married | job |
|---|---|---|---|---|---|
| 0 | jack | 20 | hockey | yes | student |
| 1 | ben | 19 | chess | no | / |
| 2 | lisa | 30 | golf | no | / |
| 3 | anna | 34 | football | / | finance |
| 4 | dan | 26 | golf | / | retail |
为啥concat不行?
简单说,pd.concat()是「无差别拼接」:如果按行拼接(axis=0),它只会把df2的行直接加到df1后面,不会做任何键匹配。这样你会得到重复的jack行(一行来自df1,一行来自df2),而且没法把married和job合并到同一行,完全达不到你要的匹配合并效果。
内容的提问来源于stack exchange,提问作者gardangerous
相关产品推荐
相关产品推荐

