首页 > 解决方案 > 在 Pandas 中排列借方和贷方?

问题描述

我在熊猫数据框中有许多借方和贷方行(下面的一些示例数据):

+----------+-------+--------------+--------+
|   Date   | Party | Debit/Credit | Amount |
+----------+-------+--------------+--------+
| 9/1/2020 | Wells | Debit        |      4 |
| 9/1/2020 | Wells | Credit       |     -4 |
| 9/1/2020 | Wells | Debit        |      4 |
| 9/1/2020 | Wells | Debit        |      4 |
| 9/2/2020 | BOA   | Credit       |     -4 |
| 9/2/2020 | BOA   | Debit        |      4 |
| 9/3/2020 | Chase | Debit        |      4 |
+----------+-------+--------------+--------+

我正在尝试识别匹配的日期/派对对和它们抵消的金额。例如,在 9 月 1 日,您可以看到 Wells 的借方和贷方交易抵消。

我试图做的是创建一个单独的借方数据框和贷方数据框,然后在日期/派对上合并两者。

df = pd.DataFrame({'Date': ['9/1/2020','9/1/2020', '9/1/2020', '9/1/2020', '9/2/2020', '9/2/2020', '9/3/2020'],
                  'Party': ['Wells', 'Wells', 'Wells', 'Wells', 'BOA', 'BOA', 'Chase'],
                  'Debit/Credit': ['Debit', 'Credit', 'Debit', 'Debit', 'Credit', 'Debit', 'Debit'],
                  'Amount': [4, -4, 4, 4, -4, 4, 4]})
debit_df = df.loc[df['Debit/Credit'] == 'Debit']
credit_df = df.loc[df['Debit/Credit'] == 'Credit']
offset_df= debit_df.merge(credit_df, on = ['Date', 'Party'])
matching_trans = offset_df.loc[offset_df['Amount_x'] == abs(offset_df['Amount_y'])]

这种方法的问题在于,我显然会拉出一个笛卡尔积,其中有多个类似的 Wells 交易。有没有办法仅识别 Wells 的匹配对(即借方 4,贷方 -4)只是它出现的次数?我的数据要大得多,但在此示例中,您将在最终matching_trans数据框中仅返回 1 个结果。

标签: pythonpandas

解决方案


如果您只需要这种情况发生的次数,您可以比较匹配实例的计数。首先为借方和贷方计算每个日期/方的相似金额:

debit_df = df.loc[df['Debit/Credit'] == 'Debit'].groupby(['Date', 'Party', 'Amount']).count().reset_index()
credit_df = df.loc[df['Debit/Credit'] == 'Credit'].groupby(['Date', 'Party', 'Amount']).count().reset_index()

然后将其中一个值更改为负数,因此它也可以用于匹配:

credit_df.rename(columns={'Amount':'Credit_Amount'}, inplace=True)
credit_df['Amount'] = -credit_df['Credit_Amount']

最后匹配 Date、Party 和 Amount 上的两个 dfs,删除 NA 并找到偏移量:

matching_trans = debit_df.merge(credit_df, on=['Date', 'Party', 'Amount'], how='left').dropna(axis=0)
matching_trans.rename(columns={'Amount':'Debit_Amount', 'Debit/Credit_x':'Debit_count',
                               'Debit/Credit_y':'Credit_count'}, inplace=True)
matching_trans['offset_count'] = matching_trans.apply(lambda x: min(x.Credit_count, x.Debit_count),axis=1)

“offset_count”将为您提供每个日期/派对组合的偏移量。


推荐阅读