如何在Pandas中统计当前行之前所有行的指定列累计值(排除当前行)
Pandas 计算历史累积进球/失球数(排除当前行)
问题描述
现有如下已按日期排序的比赛数据:
import pandas as pd labels = ['date', 'name', 'opponent', 'gf', 'ga'] data = [ ['2023-08-5', 'Liverpool', 'Man Utd', 5, 0 ], ['2023-08-10', 'Liverpool', 'Everton', 0, 0 ], ['2023-08-14', 'Liverpool', 'Tottenham', 3, 2 ], ['2023-08-18', 'Liverpool', 'Arsenal', 4, 4 ], ['2023-08-27', 'Liverpool', 'Man City', 0, 0 ], ] df = pd.DataFrame(data, columns=labels)
需要为每行计算之前所有比赛的gf(进球数)和ga(失球数)的累积总和,排除当前行,最终目标结果如下:
# 目标结果结构 labels = ['date', 'name', 'opponent', 'gf', 'ga', 'total_gf', 'total_ga'] data = [ ['2023-08-5', 'Liverpool', 'Man Utd', 5, 0, 0, 0 ], ['2023-08-10', 'Liverpool', 'Everton', 0, 0, 5, 0 ], ['2023-08-14', 'Liverpool', 'Tottenham', 3, 2, 5, 0 ], ['2023-08-18', 'Liverpool', 'Arsenal', 4, 4, 8, 2 ], ['2023-08-27', 'Liverpool', 'Man City', 0, 0, 12, 6 ], ]
尝试过expanding()方法,但它会包含当前行;rolling()的closed='left'参数无法直接适配累积求和场景。
解决方案
方法1:cumsum() + shift()
cumsum()计算包含当前行的累积和,通过shift(1)将结果向下偏移一行,并用fill_value=0填充第一行空值,刚好得到之前所有行的总和:
df['total_gf'] = df['gf'].cumsum().shift(fill_value=0) df['total_ga'] = df['ga'].cumsum().shift(fill_value=0)
方法2:expanding().sum() 减去当前行值
既然expanding().sum()会包含当前行,直接减去当前行的gf/ga值,即可得到之前所有行的累积总和:
df['total_gf'] = df['gf'].expanding().sum() - df['gf'] df['total_ga'] = df['ga'].expanding().sum() - df['ga']
验证结果
两种方法均可得到符合预期的结果:
date name opponent gf ga total_gf total_ga 0 2023-08-5 Liverpool Man Utd 5 0 0 0 1 2023-08-10 Liverpool Everton 0 0 5 0 2 2023-08-14 Liverpool Tottenham 3 2 5 0 3 2023-08-18 Liverpool Arsenal 4 4 8 2 4 2023-08-27 Liverpool Man City 0 0 12 6
内容的提问来源于stack exchange,提问作者Ewan
相关产品推荐
相关产品推荐

