如何在Pandas DataFrame中按ID逐月计算环比差值及增长率
解决方案
问题根源
你代码里的核心错误是分组时同时包含了ID和MONTH,这样每个ID+MONTH的组合都会成为一个独立分组,每个分组里只有1条数据,调用shift()或pct_change()自然返回全NaN。
正确实现步骤
- 先按
ID和MONTH对数据排序,保证每个ID下的月份是连续递增的; - 仅按
ID分组,计算环比差值和增长率; - 将首行的NaN值替换为0(对应每个ID的第一个月没有上月数据,差值和增长率为0);
- 注意增长率需要将
pct_change()的结果乘以100,转换成百分比格式。
完整代码
# 先排序(建议避免使用inplace=True,防止修改原数据) df_sorted = df_all.sort_values(['ID', 'MONTH']).reset_index(drop=True) # 按ID分组计算环比差值 df_sorted['Variance'] = df_sorted['TOTAL'] - df_sorted.groupby('ID')['TOTAL'].shift().fillna(0) # 按ID分组计算环比增长率(转换为百分比,保留1位小数) df_sorted['Variance %'] = df_sorted.groupby('ID')['TOTAL'].pct_change().fillna(0) * 100 df_sorted['Variance %'] = df_sorted['Variance %'].round(1)
结果示例
处理后的数据前几行如下:
| ID | MONTH | TOTAL | Variance | Variance % | |
|---|---|---|---|---|---|
| 0 | REF1 | 1 | 500 | 0 | 0.0 |
| 1 | REF1 | 2 | 501 | 1 | 0.2 |
| 2 | REF1 | 3 | 620 | 119 | 23.8 |
| 3 | REF2 | 6 | 1501 | 0 | 0.0 |
| 4 | REF2 | 7 | 6501 | 5000 | 333.1 |
内容的提问来源于stack exchange,提问作者Ryan1234
相关产品推荐
相关产品推荐

