You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于自定义键的Pandas左连接数据行数异常问题求助

问题场景与异常现象

现有两个CSV文件:OrderOne(约105k条记录)和OrderTwo(约115k条记录)。需求为给OrderTwo新增一列,标记每条记录是否存在于OrderOne中(存在则为TRUE,否则为FALSE)并输出文件。因无现成共享键,自定义匹配键为Forename与Surname拼接后去空格转大写的值。

处理数据后自定义键列显示正常,但执行左连接后结果行数约179k(预期与OrderTwo一致为115k);直接去重后行数又过少,无法得到正确结果。


问题原因

左连接后行数膨胀是因为OrderOne中存在重复的FNSN匹配键:当OrderTwo的某条记录匹配到OrderOne中多个相同FNSN的记录时,会生成多条重复行,导致总行数超出预期。直接去重则会误删原本应保留的有效记录,最终结果行数异常。


解决方案

方案1:用isin()直接判断(推荐,更高效)

提取OrderOne的唯一FNSN集合,直接给OrderTwo标记是否存在,完全避免连接带来的行数膨胀问题。

import pandas as pd

# 处理OrderOne,提取唯一匹配键集合
orderoneData = pd.read_csv('orderone.csv', usecols=['Forename', 'Surname'])
orderoneData["FNSN"] = orderoneData['Forename'].str.strip() + orderoneData["Surname"].str.strip()
orderoneData["FNSN"] = orderoneData["FNSN"].str.upper()
unique_fnsn = set(orderoneData["FNSN"].unique())

# 处理OrderTwo并标记
ordertwoData = pd.read_csv('ordertwo.csv')
ordertwoData["FNSN"] = ordertwoData['Forename'].str.strip() + ordertwoData["Surname"].str.strip()
ordertwoData["FNSN"] = ordertwoData["FNSN"].str.upper()

# 新增标记列
ordertwoData["Exists_in_OrderOne"] = ordertwoData["FNSN"].isin(unique_fnsn)

# 输出结果,可根据需求选择是否保留FNSN列
ordertwoData.to_csv("result.csv", index=False)

方案2:修正merge逻辑(先去重OrderOne)

先对OrderOne的FNSN键去重,确保每个匹配键仅保留一条记录,再执行左连接,避免重复匹配导致的行数膨胀。

import pandas as pd

# 处理OrderOne并去重匹配键
orderoneData = pd.read_csv('orderone.csv', usecols=['Customer Reference','Forename', 'Surname'])
orderoneData["FNSN"] = orderoneData['Forename'].str.strip() + orderoneData["Surname"].str.strip()
orderoneData["FNSN"] = orderoneData["FNSN"].str.upper()
# 仅保留每个FNSN的第一条记录
orderone_unique = orderoneData.drop_duplicates(subset=["FNSN"], keep='first')

# 处理OrderTwo
ordertwoData = pd.read_csv('ordertwo.csv')
ordertwoData["FNSN"] = ordertwoData['Forename'].str.strip() + ordertwoData["Surname"].str.strip()
ordertwoData["FNSN"] = ordertwoData["FNSN"].str.upper()

# 左连接并转换为布尔标记
d = ordertwoData.merge(
    orderone_unique[["FNSN"]],
    on=['FNSN'],
    how='left',
    indicator='Exists_in_OrderOne'
)
d["Exists_in_OrderOne"] = d["Exists_in_OrderOne"] == 'both'

# 输出结果,行数与OrderTwo一致
d.to_csv("result.csv", index=False)

内容的提问来源于stack exchange,提问作者brummie49

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 15:35:28