根据日期范围和值匹配合并熊猫数据框

时间:2019-06-18 03:44:32

标签: python pandas numpy

我希望自动进行银行交易对帐。有2个表,银行表和系统表,因此系统表中的交易会延迟几天。这些表的长度各不相同,并且交易记录不一对一。

问题在于找到一种一致的方法来识别和分组对帐和非对帐交易。我遇到的第一个挑战是根据日期范围和金额联接/合并表。 Pandas.merge_asof适合于基于日期范围的联接,但仅限于1个基于列的联接。

请参阅以下示例表:

bankdf = pd.DataFrame({'BankDate': pd.date_range('2018-12-28', periods=10, freq='3D'), 'Amount': np.array([140,107,132,188,75,152,88,159,132,107])})
systemdf = pd.DataFrame({'SystemCreditDate': pd.date_range('2019-01-04', periods=9, freq='3D'), 'Amount': np.array([107,132,190,75,152,88,110,132,132])})

bankdf
Out[119]: 
   Amount   BankDate
0     140 2018-12-28
1     107 2018-12-31
2     132 2019-01-03
3     188 2019-01-06
4      75 2019-01-09
5     152 2019-01-12
6      88 2019-01-15
7     159 2019-01-18
8     132 2019-01-21
9     107 2019-01-24

systemdf
Out[120]: 
   Amount SystemCreditDate
0     107       2019-01-04
1     132       2019-01-07
2     190       2019-01-10
3      75       2019-01-13
4     152       2019-01-16
5      88       2019-01-19
6     110       2019-01-22
7     132       2019-01-25
8     132       2019-01-28

将需要根据“金额”匹配且日期差小于6天(SystemCreditDate-BankDate)<6)连接这两个表。

最终结果应如下所示:

   Amount   BankDate SystemCreditDate
1     107 2018-12-31 2019-01-04
2     132 2019-01-03 2019-01-07
3      75 2019-01-09 2019-01-13
4     152 2019-01-12 2019-01-16
5      88 2019-01-15 2019-01-19
6     132 2019-01-21 2019-01-25

1 个答案:

答案 0 :(得分:0)

使用DataFrame.merge并删除不遵循规则的行:

df = bankdf.merge(systemdf)
mask = (df['SystemCreditDate']-df['BankDate']).abs().dt.days<6
df = df.loc[mask, :]

print(df)

     BankDate  Amount SystemCreditDate
0  2018-12-31     107       2019-01-04
2  2019-01-03     132       2019-01-07
6  2019-01-21     132       2019-01-25
8  2019-01-09      75       2019-01-13
9  2019-01-12     152       2019-01-16
10 2019-01-15      88       2019-01-19

或删除负数天:

df = bankdf.merge(systemdf)
mask = (df['SystemCreditDate']-df['BankDate']).dt.days
mask = mask.le(6) & ~mask.lt(0)
df = df.loc[mask, :]