如何在Pandas中合并含重复关联列值的两个DataFrame?
合并含重复关联列的Pandas DataFrame(按组内序号对齐)
问题场景
现有两个包含重复id列的DataFrame,需要合并时避免笛卡尔积,实现同id下按行序一一对应,多余的行补NaN的效果。示例数据如下:
import pandas as pd import numpy as np df1 = pd.DataFrame({'id': [1, 2, 2, 2, 3, 3, 3, 3, 4], 'tr1': [10, 80, 50, 40, 60, 20, 70, 90, 30]}) df2 = pd.DataFrame({'id': [1, 1, 1, 2, 2, 3, 3], 'tr2': [15, 45, 55, 35, 95, 75, 65]})
直接使用df1.merge(df2, how='outer')会产生笛卡尔积,不符合需求;手动添加全局序号的方式也无法正确对齐同id内的行。
期望输出:
| id | tr1 | tr2 |
|---|---|---|
| 1 | 10 | 15 |
| 1 | NaN | 45 |
| 1 | NaN | 55 |
| 2 | 80 | 35 |
| 2 | 50 | 95 |
| 2 | 40 | NaN |
| 3 | 60 | 75 |
| 3 | 20 | 65 |
| 3 | 70 | NaN |
| 3 | 90 | NaN |
| 4 | 30 | NaN |
解决方案
核心思路是给每个DataFrame按id分组后添加组内的行序号,然后以id+组内序号作为连接键进行外连接,就能实现同id下的行序对齐。
实现代码
import pandas as pd # 给df1添加组内序号 df1['seq'] = df1.groupby('id').cumcount() # 给df2添加组内序号 df2['seq'] = df2.groupby('id').cumcount() # 以id和seq为键做外连接 merged_df = df1.merge(df2, on=['id', 'seq'], how='outer') # 移除seq列,整理结果 result = merged_df[['id', 'tr1', 'tr2']].sort_values(by=['id', 'seq']).reset_index(drop=True) print(result)
代码说明
- 添加组内序号:使用
groupby('id').cumcount(),会对每个id组内的行从0开始计数,这样同id下的每一行都有唯一的组内序号,确保对齐的准确性。 - 外连接:以
id和seq作为连接键,外连接会保留两个DataFrame中所有的(id, seq)组合,对应不上的列自动补NaN。 - 整理结果:移除辅助的
seq列,按id和seq排序后重置索引,得到符合预期的输出。
输出验证
运行上述代码后,输出结果与期望完全一致:
id tr1 tr2 0 1 10.0 15.0 1 1 NaN 45.0 2 1 NaN 55.0 3 2 80.0 35.0 4 2 50.0 95.0 5 2 40.0 NaN 6 3 60.0 75.0 7 3 20.0 65.0 8 3 70.0 NaN 9 3 90.0 NaN 10 4 30.0 NaN
内容的提问来源于stack exchange,提问作者Adam Majdi
相关产品推荐
相关产品推荐

