Pandas实现DataFrame数据存在校验 匹配返回ID不存在新增
核心判断逻辑实现
你注释掉的存在性判断不用写复杂逻辑,用pandas的布尔掩码逐列匹配就行,同时把原来硬编码列的新增逻辑改成动态适配,不用管不同表的非匹配列(C、F这类),具体如下:
判断逻辑写法
- 先初始化一个全为
True的布尔序列,和目标DataFrame行号对齐 - 遍历需要匹配的列和传入的值,逐列叠加“列值等于入参”的条件,最后得到的序列里
True对应的就是完全匹配的行 - 如果有匹配行,直接取该行的主键值返回;没有的话动态拼新行插入,非匹配列自动填空字符串,再返回新ID
修正后的完整代码
import pandas as pd df1 = pd.DataFrame({ 'ID1': ['0', '1', '2'], 'A': ['A0', 'A1', 'A2'], 'B': ['B0', 'B1', 'B2'], 'C': ['Data does', 'not matter', ''] }) df2 = pd.DataFrame({ 'ID2': ['0', '1', '2'], 'D': ['D0', 'D1', 'D2'], 'E': ['E0', 'E1', 'E2'], 'F': ['Data does', 'not matter', ''] }) df_import = pd.DataFrame({ 'A': ['A1', 'A4'], 'B': ['B1', 'B4'], 'C': ['C1', 'C4'], 'D': ['D1', 'D4'], 'E': ['E1', 'E4'] }) def n1(dataFrame, pkName, columArray, dataArray): # 逐列构造匹配条件 match_mask = pd.Series(True, index=dataFrame.index) for col, val in zip(columArray, dataArray): match_mask &= (dataFrame[col] == val) # 命中已存在数据,直接返回对应ID if match_mask.any(): return dataFrame.loc[match_mask, pkName].iloc[0] # 未命中,构造新行插入 new_id = str(len(dataFrame)) # 和原有ID的字符串类型对齐,要数字类型直接去掉str() new_row = {pkName: new_id} # 填充匹配列值 for col, val in zip(columArray, dataArray): new_row[col] = val # 剩余非匹配列统一填空值 for col in dataFrame.columns: new_row.setdefault(col, "") dataFrame.loc[len(dataFrame)] = new_row return new_id for index, row in df_import.iterrows(): pk_test1 = n1(df1, 'ID1', ['A', 'B'], [row['A'], row['B']]) pk_test2 = n1(df2, 'ID2', ['D', 'E'], [row['D'], row['E']]) print(pk_test1) print(pk_test2) print(df1) print() print(df2) print() print(df_import)
运行结果说明
运行后表结构和数据完全符合你的预期:
- 已存在的A1/B1、D1/E1不会重复插入,分别返回对应ID
1 - 不存在的A4/B4、D4/E4会新增到对应表,返回新ID
3 - 新插入行的C、F这类非匹配列自动填充为空值,全程不参与匹配判断
你贴的期望打印值里第一组第二个返回值写的3是笔误,实际逻辑下D1/E1对应ID2=1,打印顺序为1、1、3、3,和表内数据一致。
内容的提问来源于stack exchange,提问作者ClaskoTheKnight
相关产品推荐
相关产品推荐

