如何在Python中合并Pandas透视表?解决重复数据问题
问题描述
我尝试合并两个Pandas透视表,使用merge方法后虽能运行,但结果不符合预期,出现了重复数据。以下是我的代码、两个透视表示例以及期望的合并结果,求正确实现方法?
现有代码
df1.fillna('', inplace=True) df1.reset_index(inplace=True) df2.fillna('', inplace=True) df2.reset_index(inplace=True) df = pd.merge(df1, df2, how='left', on=['KEY1', 'KEY2'])
第一个透视表(df1)
KEY1 KEY2 KEY3 Column_A0 Column_A1 Column_A2 Row_X0 Row_Y0 Row_Z0 123 123 Row_Y1 Row_Z0 456 Row_Z1 789 789 Row_X1 Row_Y0 Row_Z0 123 Row_Z1 789 Row_Z2 456 789
第二个透视表(df2)
KEY1 KEY2 KEY3 Column_B0 Column_B1 Column_B2 Column_B3 Row_X0 Row_Y0 Row_W0 1 234 Row_W1 2 345 Row_W2 3 456 Row_Y1 Row_W0 4 567 1 234 Row_W1 7 890 2 345 Row_W2 8 901 3 456 Row_W3 9 12 4 567 Row_X1 Row_Y0 Row_W0 7 890 Row_W1 8 901 Row_W2 9 12
期望合并结果
KEY1 KEY2 KEY3_X Column_A0 Column_A1 Column_A2 KEY3_Y Column_B0 Column_B1 Column_B2 Column_B3 Row_X0 Row_Y0 Row_Z0 123 123 Row_W0 1 234 Row_W1 2 345 Row_W2 3 456 Row_Y1 Row_Z0 456 Row_W0 4 567 1 234 Row_Z1 789 789 Row_W1 7 890 2 345 Row_W2 8 901 3 456 Row_W3 9 12 4 567 Row_W0 7 890 Row_X1 Row_Y0 Row_Z0 123 Row_W1 8 901 Row_Z1 789 Row_W2 9 12 Row_Z2 456 789
解决方案
你当前用merge按KEY1和KEY2左连接时,会把df1里每个KEY1+KEY2组合和df2里对应组合的所有行一一匹配,导致笛卡尔积式的重复数据。要实现你要的“一对多对齐展示”效果,需要先重命名冲突列,再通过分组序号对齐两个表的行,具体代码如下:
import pandas as pd # 1. 重命名两个表的KEY3列,避免合并后列名冲突 df1 = df1.rename(columns={'KEY3': 'KEY3_X'}) df2 = df2.rename(columns={'KEY3': 'KEY3_Y'}) # 2. 获取两个表中所有KEY1+KEY2的唯一组合,作为连接基准 key_pairs = pd.concat([df1[['KEY1', 'KEY2']], df2[['KEY1', 'KEY2']]]).drop_duplicates() # 3. 分别扩展两个表,确保每个KEY1+KEY2组合下的行都被保留 df1_expanded = key_pairs.merge(df1, on=['KEY1', 'KEY2'], how='left') df2_expanded = key_pairs.merge(df2, on=['KEY1', 'KEY2'], how='left') # 4. 给每个KEY1+KEY2组内的行分配序号,用于对齐 df1_expanded['group_idx'] = df1_expanded.groupby(['KEY1', 'KEY2']).cumcount() df2_expanded['group_idx'] = df2_expanded.groupby(['KEY1', 'KEY2']).cumcount() # 5. 按KEY1、KEY2和分组序号合并,实现行对齐 merged_df = pd.merge(df1_expanded, df2_expanded, on=['KEY1', 'KEY2', 'group_idx'], how='outer') # 6. 处理空值并调整列顺序,匹配期望结果 merged_df.fillna('', inplace=True) final_cols = ['KEY1', 'KEY2', 'KEY3_X', 'Column_A0', 'Column_A1', 'Column_A2', 'KEY3_Y', 'Column_B0', 'Column_B1', 'Column_B2', 'Column_B3'] merged_df = merged_df[final_cols] print(merged_df)
代码说明
- 重命名
KEY3是为了区分两个表的主键列,避免合并后列名冲突; - 分组序号对齐的方式,能让同一个
KEY1+KEY2组合下,df1的行和df2的行按顺序一一对应,不会产生重复; - 最后调整列顺序,确保输出结构和你期望的一致。
内容的提问来源于stack exchange,提问作者Qwerty
相关产品推荐
相关产品推荐

