Pandas左连接结果行数不符预期问题求助
问题分析与解决方案
行数异常的原因
首先明确:how='left'的左连接必然保留左表(Frame A)的所有行,不可能减少行数。你描述的“行数从367469(Frame B的行数)增加到1490420”应该是混淆了表的对应关系——大概率是你误将Frame B的行数当成了左表初始行数,或者查看shape时搞混了表。
如果实际是Frame A的8666515行膨胀到1490420+行,核心原因是:Frame B中存在重复的[OB_ID, CA_ID]组合。当左表某一行的连接键在右表中出现N次时,这一行会被复制N次,最终行数=左表行数 + 匹配到的重复次数总和。
举个简单例子:若Frame A有1行[4,4],Frame B有2行[4,4],左连接后这一行会变成2行,直接导致行数翻倍。
另外,你的代码把Frame B的342列全部合并到结果中,不仅造成列数冗余,也可能干扰你对行数变化的判断。
分步解决方法
1. 检查并清理Frame B的重复连接键
先确认Frame B中是否存在重复的连接键组合:
# 标记所有重复的连接键行 duplicate_keys = frameB.duplicated(subset=['OB_ID', 'CA_ID'], keep=False) print("Frame B中重复的[OB_ID, CA_ID]组合行数:", duplicate_keys.sum()) # 查看具体重复行 print(frameB[duplicate_keys].sort_values(['OB_ID', 'CA_ID']))
根据业务需求去重,比如保留每个连接键组合的第一行:
frameB_clean = frameB.drop_duplicates(subset=['OB_ID', 'CA_ID'], keep='first')
2. 仅合并需要的colZ列
不需要合并Frame B的全部342列,只提取目标列再做连接,减少冗余:
# 仅保留连接键和colZ列 frameB_colZ = frameB[['OB_ID', 'CA_ID', 'colZ']] # 去重(根据第一步的检查结果决定是否执行) frameB_colZ = frameB_colZ.drop_duplicates(subset=['OB_ID', 'CA_ID'], keep='first') # 左连接 df3 = pd.merge(frameA, frameB_colZ, on=['OB_ID', 'CA_ID'], how='left') # 将NaN替换为你需要的标识 df3['colZ'] = df3['colZ'].fillna('NA/unknown')
3. 验证结果行数
执行完上述代码后,df3.shape[0]应该等于Frame A的原始行数8666515,这才符合左连接保留左表所有行的预期。
额外排查点
如果行数依然异常,检查Frame A的连接键是否存在缺失值:
# 检查连接键的缺失情况 print("Frame A中OB_ID缺失数:", frameA['OB_ID'].isna().sum()) print("Frame A中CA_ID缺失数:", frameA['CA_ID'].isna().sum())
即便连接键有缺失,左连接也会保留这些行,只是合并列会填充NaN,不会减少总行数。
内容的提问来源于stack exchange,提问作者Obiii
相关产品推荐
相关产品推荐

