如何合并Pandas DataFrame且不产生重复行?
解决Pandas合并DataFrame时避免同组笛卡尔积的问题
当两个DataFrame的关联列(如示例中的C列)存在重复值时,直接使用pd.merge会生成笛卡尔积,导致大量重复行。要实现同组内按行一一对应合并,可以通过添加组内行号作为额外合并键来解决。
具体步骤:
- 为每个DataFrame按关联列分组,添加组内的行序号(确保同组内每行有唯一标识)
- 使用关联列+行序号作为合并键进行合并
- (可选)删除临时添加的行序号列
代码实现:
首先定义示例中的两个DataFrame:
import pandas as pd # DF1 df1 = pd.DataFrame(columns=['A','B','C']) df1['A'] = ['2_21','2_34'] df1['B'] = ['X1','X2'] df1['C'] = ['2','2'] # DF2 df2 = pd.DataFrame(columns=['D','E','C']) df2['D'] = ['2_27','2_35'] df2['E'] = ['Y1','Y2'] df2['C'] = ['2','2']
添加组内行号并执行合并:
# 给每个DF按C列分组,生成组内行号 df1['group_idx'] = df1.groupby('C').cumcount() df2['group_idx'] = df2.groupby('C').cumcount() # 以C列+组内行号作为合并键 merged_df = df1.merge(df2, on=['C', 'group_idx'], how='left') # 删除临时生成的行号列 merged_df = merged_df.drop('group_idx', axis=1) print(merged_df)
输出结果:
A B C D E 0 2_21 X1 2 2_27 Y1 1 2_34 X2 2 2_35 Y2
原理说明:
groupby('C').cumcount()会在每个C值的分组内,从0开始为每行分配递增序号,让同组内的每行拥有唯一标识。合并时同时使用C和group_idx作为键,就能让df1中C组的第1行仅匹配df2中C组的第1行,第2行匹配第2行,从根源上避免笛卡尔积的生成。
内容的提问来源于stack exchange,提问作者btroppo
相关产品推荐
相关产品推荐

