使用Python的groupby、cumsum和max计算月末余额及最高值
解决每月月末余额及最高余额计算问题
问题背景
你有如下交易数据记录(包含日期、交易金额、月份和当前余额):
| Date | Amount | Month | Balance | |
|---|---|---|---|---|
| 0 | 9/4/2018 | 32000.00 | 9 | 32000.00 |
| 1 | 9/30/2018 | 29.59 | 9 | 32029.59 |
| 2 | 10/1/2018 | 34.05 | 10 | 32063.64 |
| 3 | 10/31/2018 | -1000.00 | 10 | 31063.64 |
| 4 | 11/1/2018 | 1500.00 | 11 | 32563.64 |
| 5 | 11/30/2018 | 33.06 | 11 | 32596.70 |
| 6 | 12/1/2018 | -2000.00 | 12 | 30596.70 |
| 7 | 12/31/2018 | 34.26 | 12 | 30630.96 |
你的需求是:
- 计算每个月的月末余额(即每个月最后一笔交易后的余额)
- 找出所有月末余额中的最高值
你尝试了以下代码,但未得到预期结果:
month_end_balance = yearly_df.groupby('Month')['Amount'].cumsum() max_month_end_balance = month_end_balance.max()
错误原因分析
你当前的代码逻辑存在两个核心问题:
groupby('Month')['Amount'].cumsum()是对每个月内的交易金额单独累加,但你的Balance列本身已经是全局累计的结果,单独累加每月的Amount无法得到正确的月末余额(比如10月单独累加的结果是34.05-1000=-965.95,但实际月末余额是基于9月的余额继续计算的)。- 即使累加逻辑正确,
cumsum()会返回每行的累加值,而非每个月的最后一个值,所以无法直接提取月末余额。
正确解决方案
由于你的Balance列已经是每笔交易后的实时余额,我们只需要提取每个月最后一条记录的Balance即可,这就是该月的月末余额。具体代码如下:
步骤1:计算每月月末余额
# 按Month分组,取每组最后一行的Balance作为月末余额 month_end_balance = yearly_df.groupby('Month')['Balance'].last()
执行后会得到你期望的结果:
Month 9 32029.59 10 31063.64 11 32596.70 12 30630.96 Name: Balance, dtype: float64
步骤2:计算最高月末余额
直接对上面的结果调用max()即可:
max_month_end_balance = month_end_balance.max()
结果为:32596.70
额外说明
如果你的数据没有预先计算好Balance列,需要从Amount从头累计计算的话,可以这样处理:
# 先计算全局累计余额 yearly_df['Calculated_Balance'] = yearly_df['Amount'].cumsum() # 再取每月最后一行的累计余额 month_end_balance = yearly_df.groupby('Month')['Calculated_Balance'].last() max_month_end_balance = month_end_balance.max()
这也能得到和你期望一致的结果。
内容的提问来源于stack exchange,提问作者b00kgrrl
相关产品推荐
相关产品推荐

