基于Pandas的分组累计求和与日期条件的跨客户发票-支付匹配问题求解
问题描述
我有三个Pandas DataFrame,分别用于记录客户相似度、发票和支付数据:
- df_sim:记录因数据错误导致支付与我方发票不匹配的客户(Cust1),以及与其名称相似或相同的其他客户(Cust2)的相似度信息,需要为每一组Cust1-Cust2判断是否匹配成功。
- df_inv:记录我方开具给df_sim中Cust1客户的发票数据,包含客户名称、发票金额、发票日期字段。
- df_paym:记录我方系统中df_sim里Cust2客户的支付数据,包含客户名称、支付金额、支付日期字段。
具体需求
- 对每个Cust1客户,需将其发票金额按「发票日期≤支付日期」的条件进行累计求和,并在1美元的误差阈值内,与对应Cust2客户的支付金额的所有可能组合进行匹配,直到累计金额达到发票总和。
- 若某一组Cust1-Cust2匹配成功(例如df_sim中第一行的ABC-ABC组合),则该Cust1对应的后续相似客户行需跳过匹配。
- 最终需为三个DataFrame添加「Match (Y/N)」列,标识对应行是否匹配成功,预期输出如下:
df_sim(客户相似度表)
| Cust1 | Cust2 | 相似度百分比(Similarity%) | 是否匹配(Match (Y/N)) |
|---|---|---|---|
| ABC | ABC | 1.00 | Y |
| ABC | ABB | 0.66 | N |
| ABC | AYZ | 0.33 | N |
| DEF | DEA | 0.66 | N |
| DEF | DEB | 0.66 | Y |
| DEF | DEC | 0.33 | N |
| GHI | GAB | 0.33 | Y |
| LMN | LMA | 0.66 | N |
| LMN | LAB | 0.33 | Y |
| OPQ | OPA | 0.66 | Y |
df_inv(发票表)
| Cust1 | 金额(Amount) | 日期(Date) | 是否匹配(Match (Y/N)) |
|---|---|---|---|
| ABC | 10.00 | 01/01/21 | Y |
| ABC | 10.00 | 01/01/21 | Y |
| ABC | 29.50 | 01/01/21 | Y |
| DEF | 40.00 | 01/02/21 | Y |
| GHI | 49.00 | 01/02/21 | Y |
| GHI | 10.00 | 01/02/21 | Y |
| LMN | 100.00 | 01/03/21 | Y |
| LMN | 0.99 | 01/03/21 | Y |
| OPQ | 190.00 | 01/03/21 | Y |
| OPQ | 10.99 | 01/03/21 | Y |
df_paym(支付表)
| Cust1 | 金额(Amount) | 日期(Date) | 是否匹配(Match (Y/N)) |
|---|---|---|---|
| ABC | 50.00 | 01/02/21 | Y |
| ABB | 50.00 | 01/02/21 | N |
| DEA | 40.00 | 31/12/20 | N |
| DEB | 40.00 | 01/03/21 | Y |
| GAB | 60.00 | 01/03/21 | Y |
| LMA | 98.00 | 01/04/21 | N |
| LAB | 100.99 | 01/04/21 | Y |
| OPA | 200.00 | 01/04/21 | Y |
现有代码问题
我已编写了初步代码,但仅能实现发票与支付金额的精确匹配,无法实现日期条件判断及支付组合的累计匹配逻辑,现有代码如下:
import pandas as pd df_sim = pd.DataFrame({'Cust1':['ABC', 'ABC', 'ABC', 'DEF','DEF','DEF','GHI', 'LMN', 'LMN', 'OPQ'], 'Cust2': ['ABC', 'ABB', 'AYZ', 'DEA', 'DEB', 'DEC', 'GAB', 'LMA', 'LAB', 'OPA'], 'similarity%': [1, .66, .33, .66, .66, .33, .33, .66, .33, .66]}) df_inv = pd.DataFrame({'Cust1':['ABC', 'ABC', 'ABC', 'DEF', 'GHI', 'GHI', 'LMN', 'LMN', 'OPQ', 'OPQ'], 'Amount': [10, 10, 29.5, 40, 49, 10, 100, 0.99, 190, 10.99], 'Date': ['01/01/2021', '01/01/2021', '01/01/2021','01/02/2021', '01/02/2021','01/02/2021','01/03/2021','01/03/2021','01/03/2021','01/03/2021']}) df_paym = pd.DataFrame({'Cust1':['ABC', 'ABB', 'DEA', 'DEB', 'GAB', 'LMA', 'LAB', 'OPA'], 'Amount': [50, 50, 40, 40, 60, 98, 100.99, 200], 'Date': ['01/02/2021', '01/02/2021', '31/12/2020', '01/03/2021', '01/03/2021', '01/04/2021', '01/04/2021','01/04/2021']}) df_inv_grpd = df_inv.groupby(['Cust1', 'Date'])['Amount'].sum().reset_index() for cust1, cust2 in zip(df_sim['Cust1'], df_sim['Cust2']): if df_inv_grpd[df_inv_grpd['Cust1']==cust1]['Amount'].values in (df_paym[df_paym['Cust1']==cust2]['Amount'].to_numpy()): print(cust1, " ", cust2, " ", ":", 'OK') else: print(cust1, " ", cust2, " ", ":", 'NO')
请求协助
请帮忙完善代码,实现以下功能:
- 满足「发票日期≤支付日期」条件的分组累计求和
- 支付金额组合的累计匹配逻辑
- 1美元误差阈值的判断
- 匹配成功后跳过该Cust1后续相似客户的逻辑
内容的提问来源于stack exchange,提问作者Jbuzz
相关产品推荐
相关产品推荐

