用DataFrames实现Access SQL去重追加逻辑:将B中新增记录加入A
用Pandas DataFrames实现Access的重复记录筛选与追加逻辑
需求说明
时隔数年重新使用Python,正在用Pandas DataFrames重写旧的MS Access预算程序:
- 现有存储支出历史的大型表
dfA,以及需要追加到dfA的近期支出快照表dfB dfB中可能包含dfA已有的重复记录,需筛选出dfB中未在dfA出现过的记录,并追加到dfA中
原Access程序使用的SQL逻辑:
SELECT A.Date, A.Item, A.Debit, A.Credit, A.Balance, A.Description
FROM A LEFT JOIN B
ON(A.Date=B.Date) AND(A.Item=B.Item) AND(A.Balance=B.Balance)
WHERE(((B.Date) Is Null)) Or(((B.Item) Is Null)) Or(((B.Balance) Is Null))
示例数据
import pandas as pd dfA = pd.DataFrame({ 'Date': ['2023-01-25', '2023-01-24', '2023-01-24', '2023-01-23'], 'Item': ['Visa Purchase 21Jan Hanaro Northlakes Mango Hil ', 'Visa Purchase 21Jan Event Cinemas North North Lak', 'Visa Purchase 21Jan Event Cinemas North North Lak', 'Mcare Benefits 4880000027 Eywq'], 'Debit': [67.0, 10.2, 7.65, 39.75], 'Credit': [0.0, 0, 0, 0], 'Balance': [1830.0, 1897.99, 1908.019, 1915.84], 'Description': ['a', 'b', 'c', 'd'] }) dfB = pd.DataFrame({ 'Date': ['2023-01-23', '2023-01-23', '2023-01-23', '2023-01-23'], 'Item': ['Csc R555558Df Nett', 'Tfr Wdl BPAY Internet 25Jan05:31 208655638973732700058Deft Payments', 'Eftpos Debit 25Jan15:19 Sq *Becs Cafe Kippa-Ring Qldau', 'Mcare Benefits 4880000027 Eywq'], 'Debit': [0, 168.0, 9.0, 39.75], 'Credit': [907.92, 0, 0, 0], 'Balance': [2053.09, 1885.07, 1876.09, 1915.84], 'Description': ['z', 'x', 's', 'f']})
解决方案
核心逻辑:以Date、Item、Balance三个字段作为重复判断的唯一标识,通过左连接筛选出dfB中无匹配的记录,再追加到dfA。
实现代码
# 1. 左连接dfB与dfA,标记匹配情况 merged = dfB.merge(dfA, on=['Date', 'Item', 'Balance'], how='left', indicator=True) # 2. 筛选出dfB中未在dfA出现的记录 new_records = merged[merged['_merge'] == 'left_only'].drop(columns=['_merge']) # 3. 将新记录追加到dfA dfA_updated = pd.concat([dfA, new_records], ignore_index=True) # 查看结果 print("更新后的支出记录表:") print(dfA_updated)
代码说明
merge(how='left'):保留dfB的所有行,匹配dfA中符合Date/Item/Balance三个键的记录;indicator=True会生成_merge字段,标记每行的匹配状态。_merge == 'left_only':代表该行仅存在于dfB,即dfA中无重复记录,这部分就是需要追加的新数据。pd.concat:合并原表与新记录,ignore_index=True重置索引,避免出现重复索引问题。
注意事项
- 若
Date为日期类型,pandas会自动正确匹配;若为字符串,需确保格式完全一致(如示例中的YYYY-MM-DD)。 - 该方法基于向量运算,处理大型数据集时效率远高于循环判断,适合预算程序的大规模数据场景。
内容的提问来源于stack exchange,提问作者Mick Hawkes
相关产品推荐
相关产品推荐

