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

Pandas处理相似交易净额:剔除冲销记录保留最终发票

Pandas 发票冲销记录自动净额抵消实现

原始数据示例

问题背景

做重复发票识别时,数据集内的更正冲销记录会导致识别结果误报,需要通过Pandas自动识别并抵消金额正负匹配的冲销记录,最终仅返回有效发票记录。
示例数据中前3条属于同一张发票的关联交易,需要剔除前两行金额正负抵消的冲销记录,仅保留第3行的最终有效记录。

测试数据集

构造测试数据的代码如下:

import pandas as pd

df = pd.DataFrame({
    'Reference Number': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5},
    'InvoiceNumber': {0: 'A123', 1: 'A123', 2: 'A123', 3: 'A342', 4: 'A444'},
    'InvoiceAmount': {0: 100, 1: -100, 2: 100, 3: 123, 4: 345},
    'DocType': {0: 'IN', 1: 'AD', 2: 'IN', 3: 'IN', 4: 'IN'},
    'Date': {0: '1/1/2022',
             1: '1/2/2022',
             2: '1/3/2022',
             3: '1/3/2022',
             4: '1/3/2022'}
})

实现代码

核心逻辑为按发票号分组,按交易日期升序排列后,逐行匹配金额绝对值相等、符号相反的对冲记录对,标记后剔除:

def remove_offset_records(group_df):
    # 按交易日期排序,保证冲销匹配按业务发生顺序处理
    group_df = group_df.sort_values('Date').reset_index(drop=True)
    drop_flag = [False] * len(group_df)
    
    for idx, row in group_df.iterrows():
        if drop_flag[idx]:
            continue
        # 查找当前行之后、未被标记、金额与当前行正负抵消的第一条记录
        match_pos = group_df[
            (~pd.Series(drop_flag, index=group_df.index)) &
            (group_df.index > idx) &
            (group_df['InvoiceAmount'] == -row['InvoiceAmount'])
        ].index
        if not match_pos.empty:
            drop_flag[idx] = True
            drop_flag[match_pos[0]] = True
    
    return group_df[~pd.Series(drop_flag, index=group_df.index)]

# 按发票号分组执行过滤
clean_df = df.groupby('InvoiceNumber', group_keys=False).apply(remove_offset_records).reset_index(drop=True)

输出效果

处理完成后输出的结果符合预期:
期望结果示例
最终结果中A123发票下100、-100的两条冲销记录被剔除,仅保留最终的100元有效记录,其余无冲销的发票记录完整保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:21:43