Pandas左连接(Left Merge)后行数增加的原因排查
你遇到的这种情况,核心原因是右表(oil表)的关联键Product/Service存在重复值,具体逻辑和排查方法如下:
为什么行数会增加?
Left Join的规则是保留左表(zent)的所有行,右表(oil)中与左表关联键匹配的每一行,都会和左表对应的行进行合并。如果右表中某个Product/Service值对应多行,左表中匹配该值的行就会被复制多次,最终合并后的总行数就会超过左表原行数。
举个简单例子:左表有1行Product/Service = 机油A,右表有2行Product/Service = 机油A(比如两行的其他列数据不同),合并后这一行会变成2行,直接让总行数增加1。你的情况里总多了20行,说明这类重复匹配的情况总共贡献了20行增量。
排查与验证方法
1. 检查oil表关联键的重复次数
执行以下代码,直接统计Product/Service列的重复值数量:
print(oil['Product/Service'].duplicated().sum())
这个数字代表oil表中,有多少行的Product/Service值和之前的行重复。
2. 定位具体导致行数增加的关联键
通过以下代码,可以找出哪些Product/Service值是行数增加的“元凶”,以及每个值贡献了多少行增量:
# 统计左表每个关联键的出现次数 zent_key_counts = zent['Product/Service'].value_counts().reset_index(name='zent_row_num') # 统计右表每个关联键的出现次数 oil_key_counts = oil['Product/Service'].value_counts().reset_index(name='oil_row_num') # 合并两个统计结果,计算每个键带来的行数增量 key_increase = zent_key_counts.merge(oil_key_counts, on='Product/Service', how='left').fillna(0) key_increase['total_increase'] = key_increase['zent_row_num'] * (key_increase['oil_row_num'] - 1) # 筛选出有增量的键 problem_keys = key_increase[key_increase['total_increase'] > 0] print(problem_keys)
运行后,problem_keys会列出所有导致行数增加的关联键,以及各自带来的增量总和,总和应该刚好等于20(35948-35928)。
3. 确认oil表的去重逻辑
你提到“去重后的oil表有1371行”,但要注意:如果去重是基于整行数据而非仅Product/Service列,那么即使整行去重后,Product/Service列依然可能存在重复值(比如两行只有关联键相同,其他列不同,整行去重会保留这两行)。如果需要让oil表的Product/Service列唯一,可以针对该列去重:
# 仅保留每个Product/Service值的第一行 oil_unique = oil.drop_duplicates(subset='Product/Service', keep='first')
用这个去重后的表再做Left Join,行数就会和左表原行数一致(35928行)。
内容的提问来源于stack exchange,提问作者Viapacific

