如何在排除当日数据的情况下计算Roll Sum(滚动求和)?
问题与解决方案
原始数据
我有如下DataFrame:
| var 1 | Day |
|---|---|
| 0 | 1 |
| 0 | 2 |
| 1 | 3 |
| 1 | 4 |
| 1 | 5 |
| 1 | 6 |
| 0 | 7 |
| 0 | 8 |
需求
计算k天滚动求和(Roll Sum),求和范围不包含当日数据。以k=3为例,期望输出如下:
| var 1 | Day | sum |
|---|---|---|
| 0 | 1 | NA |
| 0 | 2 | NA |
| 1 | 3 | NA |
| 1 | 4 | 1 |
| 1 | 5 | 2 |
| 1 | 6 | 3 |
| 0 | 7 | 3 |
| 0 | 8 | 2 |
解决方案
方法1:使用rolling的closed参数(推荐,Pandas 1.2.0+)
利用rolling方法的closed='left'参数,指定窗口仅包含当前行之前的k个数据点,不包含当前行:
import pandas as pd # 构造数据 df = pd.DataFrame({ 'var 1': [0, 0, 1, 1, 1, 1, 0, 0], 'Day': [1, 2, 3, 4, 5, 6, 7, 8] }) k = 3 # 计算滚动求和,不包含当日 df['sum'] = df['var 1'].rolling(window=k, closed='left').sum() print(df)
输出结果与需求完全一致,前k行自动填充为NaN(等价于示例中的NA)。
方法2:基于累计求和(兼容旧版Pandas)
通过累计求和(cumsum)的差值实现,再手动将前k行设为NA:
import pandas as pd df = pd.DataFrame({ 'var 1': [0, 0, 1, 1, 1, 1, 0, 0], 'Day': [1, 2, 3, 4, 5, 6, 7, 8] }) k = 3 # 计算累计求和的差值 cum_sum = df['var 1'].cumsum() df['sum'] = cum_sum - cum_sum.shift(k, fill_value=0) # 前k行设为NA df.loc[:k-1, 'sum'] = pd.NA print(df)
这个方法不依赖closed参数,适合版本较低的Pandas环境。
内容的提问来源于stack exchange,提问作者doraemon
相关产品推荐
相关产品推荐

