我目前正在努力将我的数据转换为有用的数据集。我需要从第一个月到最后一个月平均分配付款。问题是付款不一致和不平等。此外,有些付款已全额支付,应根据协议数据框从第一次付款加上适用的期限开始分配。
我的表如下:
第一张表:付款
cust_id | 协议ID | 日期 | 支付 |
---|---|---|---|
1 | 一个 | 20 年 12 月 1 日 | 200 |
1 | 一个 | 2/2/21 | 200 |
1 | 一个 | 2/3/21 | 100 |
1 | 一个 | 21 年 5 月 1 日 | 200 |
1 | 乙 | 21 年 1 月 2 日 | 50 |
1 | 乙 | 21 年 1 月 9 日 | 20 |
1 | 乙 | 21 年 3 月 1 日 | 80 |
1 | 乙 | 21 年 4 月 23 日 | 90 |
2 | C | 21 年 1 月 21 日 | 600 |
3 | D | 21 年 3 月 4 日 | 150 |
3 | D | 21 年 5 月 3 日 | 150 |
这是付款数据框的代码:
payments = pd.DataFrame.from_dict({'cust_id': {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 2, 9: 3, 10: 3},
'agreement_id': {0: 'A', 1: 'A', 2: 'A', 3: 'A', 4: 'B', 5: 'B', 6: 'B', 7: 'B',
8: 'C', 9: 'D', 10: 'D'},
'date': {0: '12/1/20', 1: '2/2/21', 2: '2/3/21', 3: '5/1/21', 4: '1/2/21', 5: '1/9/21',
6: '3/1/21', 7: '4/23/21', 8: '1/21/21', 9: '3/4/21', 10: '5/3/21'},
'payment': {0: 200, 1: 200, 2: 100, 3: 200, 4: 50, 5: 20, 6: 80, 7: 90, 8: 600, 9: 150, 10: 150}})
表二:协议
协议ID | 激活 | term_months | 总费用 |
---|---|---|---|
一个 | 20 年 12 月 1 日 | 24 | 4800 |
乙 | 21 年 1 月 21 日 | 6 | 600 |
C | 21 年 1 月 21 日 | 6 | 600 |
D | 21 年 3 月 4 日 | 6 | 300 |
这是协议数据框的代码:
agreement = pd.DataFrame.from_dict({'agreement_id': {0: 'A', 1: 'B', 2: 'C', 3: 'D'}, 'activation': {0: '12/1/20', 1: '1/2/21', 2: '1/21/21', 3: '3/4/21'}, 'term_months': {0: 24, 1: 6, 2: 6, 3: 6}, 'total_fee': {0: 4800, 1: 300, 2: 600, 3: 300}})
我想要的结果如下:
cust_id | 协议ID | 日期 | 支付 |
---|---|---|---|
1 | 一个 | 20 年 12 月 1 日 | 116.67 |
1 | 一个 | 21 年 1 月 1 日 | 116.67 |
1 | 一个 | 2/1/21 | 116.67 |
1 | 一个 | 21 年 3 月 1 日 | 116.67 |
1 | 一个 | 21 年 4 月 1 日 | 116.67 |
1 | 一个 | 21 年 5 月 1 日 | 116.67 |
1 | 乙 | 21 年 1 月 1 日 | 60 |
1 | 乙 | 2/1/21 | 60 |
1 | 乙 | 21 年 3 月 1 日 | 60 |
1 | 乙 | 21 年 4 月 1 日 | 60 |
2 | C | 21 年 1 月 1 日 | 100 |
2 | C | 2/1/21 | 100 |
2 | C | 21 年 3 月 1 日 | 100 |
2 | C | 21 年 4 月 1 日 | 100 |
2 | C | 21 年 5 月 1 日 | 100 |
2 | C | 21 年 6 月 1 日 | 100 |
3 | D | 21 年 3 月 1 日 | 50 |
3 | D | 21 年 4 月 1 日 | 50 |
3 | D | 21 年 5 月 1 日 | 50 |
3 | D | 21 年 6 月 1 日 | 50 |
3 | D | 21 年 7 月 1 日 | 50 |
3 | D | 21 年 8 月 1 日 | 50 |
或者,以代码形式:
cust_id agreement_id date payment
0 1 A 12/1/20 116.67
1 1 A 1/1/21 116.67
2 1 A 2/1/21 116.67
3 1 A 3/1/21 116.67
4 1 A 4/1/21 116.67
5 1 A 5/1/21 116.67
6 1 B 1/1/21 60.00
7 1 B 2/1/21 60.00
8 1 B 3/1/21 60.00
9 1 B 4/1/21 60.00
10 2 C 1/1/21 100.00
11 2 C 2/1/21 100.00
12 2 C 3/1/21 100.00
13 2 C 4/1/21 100.00
14 2 C 5/1/21 100.00
15 2 C 6/1/21 100.00
16 3 D 3/1/21 50.00
17 3 D 4/1/21 50.00
18 3 D 5/1/21 50.00
19 3 D 6/1/21 50.00
20 3 D 7/1/21 50.00
21 3 D 8/1/21 50.00
激活日期与首次付款日期相同。
我尝试使用以下代码(由 AlexK 建议)创建另一列,但仅当总付款少于总费用时才适用。但是,当总付款等于总费用时,我需要从付款开始到月底相应地分配付款(开始加上以月为单位的条款)。
payments['date'] = pd.to_datetime(payments['date'])
resampled_payments = (payments
.set_index('date')
.groupby(['cust_id', 'agreement_id'])
.resample('MS')
.agg({'payment': sum})
.reset_index()
)
resampled_payments['avg_monthly_payment'] = (resampled_payments
.groupby(['cust_id', 'agreement_id'])['payment']
.transform('mean')
)