基于自定义键的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
相关产品推荐
相关产品推荐

