Pandas左连接处理重复关联数据 避免行重复生成新列问题咨询
Pandas 行列转换+左连接实现方案
核心逻辑是先对表B按关联字段分组排序打标,再将B表长格式转成宽格式,最后和表A直接左连接即可,不会产生表A的重复行。
步骤1:构造测试数据
首先构造你提到的两张测试表:
import pandas as pd # 构造表A df_a = pd.DataFrame({ 'ID': [1, 2], 'Data': ['Something', 'Anything'] }) # 构造表B df_b = pd.DataFrame({ 'ID': [1, 2, 3], 'A_ID': [1, 1, 2], 'Data': ['data1', 'data2', 'data3'] })
步骤2:给表B同A_ID的记录加序号
对B表按A_ID分组,给每组内的记录生成从1开始的序号,用于后续转宽表的列名后缀:
df_b['rank'] = df_b.groupby('A_ID').cumcount() + 1
步骤3:表B转宽格式
以A_ID为索引,序号为列维度,将B表的ID、Data字段转成多列:
df_b_wide = df_b.pivot(index='A_ID', columns='rank', values=['ID', 'Data']) # 重命名列匹配要求格式 df_b_wide.columns = [f'B_ID_{col[1]}' if col[0] == 'ID' else f'B_Data_{col[1]}' for col in df_b_wide.columns] # 如果需要第一个B_Data无后缀,执行下行代码即可 # df_b_wide.rename(columns={'B_Data_1':'B_Data'}, inplace=True) # 重置索引方便后续关联 df_b_wide = df_b_wide.reset_index()
步骤4:左连接得到最终表
直接用表A和转宽后的表B关联即可:
result = df_a.merge(df_b_wide, left_on='ID', right_on='A_ID', how='left').drop('A_ID', axis=1)
输出结果验证
最终输出的result结构完全符合要求:
| ID | Data | B_ID_1 | B_Data_1 | B_ID_2 | B_Data_2 |
|---|---|---|---|---|---|
| 1 | Something | 1 | data1 | 2 | data2 |
| 2 | Anything | 3 | data3 | NaN | NaN |
如果后续B表单个A_ID下出现超过2条匹配记录,无需修改逻辑,代码会自动生成对应数量的B_ID_n、B_Data_n列。
内容的提问来源于stack exchange,提问作者Kad Rys
相关产品推荐
相关产品推荐

