如何仅对Pandas DataFrame的2月行计算2天滚动求和(免全量计算)
解决大数据量下的滚动求和按需计算问题
这确实是个很实用的优化需求——当数据量极大时,全量计算滚动统计完全是做无用功,咱们可以换个思路:只提取计算目标月份滚动和所需的最小数据集,既满足回溯依赖,又避免不必要的计算。
问题回顾
先明确下场景:我们有这样的交易数据:
| DATE | AMOUNT |
|---|---|
| 2017-01-29 | 10 |
| 2017-01-30 | 20 |
| 2017-01-31 | 30 |
| 2017-02-01 | 40 |
| 2017-02-02 | 50 |
| 2017-02-03 | 60 |
要计算2天滚动求和,但只需要2月份的结果。直接全量计算再过滤的方式在大数据场景下效率太低,而且不能提前过滤2月数据(因为2月1日的滚动和需要用到1月31日的回溯数据)。
核心思路
滚动窗口的计算依赖于目标日期之前的N-1天数据(这里N=2,所以需要前1天)。所以我们只需要筛选出:
- 目标月份的所有数据
- 目标月份起始日往前推N-1天的那段数据
用这个极小的子集来计算滚动求和,最后再提取目标月份的结果即可。
具体实现代码
1. 准备数据与参数配置
import pandas as pd # 构造示例数据 data = { 'DATE': ['2017-01-29', '2017-01-30', '2017-01-31', '2017-02-01', '2017-02-02', '2017-02-03'], 'AMOUNT': [10, 20, 30, 40, 50, 60] } df = pd.DataFrame(data) df['DATE'] = pd.to_datetime(df['DATE']) # 配置核心参数 target_year = 2017 target_month = 2 window_days = 2 # 滚动窗口天数
2. 筛选最小必要数据集
# 计算目标月份的起止日期 target_month_start = pd.to_datetime(f'{target_year}-{target_month}-01') target_month_end = target_month_start + pd.offsets.MonthEnd(0) # 自动获取当月最后一天 # 计算需要回溯的起始日期:目标月第一天往前推window_days-1天 lookback_start = target_month_start - pd.Timedelta(days=window_days-1) # 筛选出仅需要的数据子集 subset_df = df[(df['DATE'] >= lookback_start) & (df['DATE'] <= target_month_end)]
3. 计算滚动求和并提取目标结果
# 设置日期索引 subset_df.set_index('DATE', inplace=True) # 在子集上计算滚动求和 rolling_sum = subset_df.rolling(f'{window_days}d')['AMOUNT'].sum() # 只保留目标月份的结果 result = rolling_sum[rolling_sum.index.month == target_month] print(result)
运行结果
DATE 2017-02-01 70.0 2017-02-02 90.0 2017-02-03 110.0 Name: AMOUNT, dtype: float64
优势说明
- 效率提升:只处理必要的数据,比如这个例子里从6行变成了4行(1月31日+2月3天),数据量越大,节省的计算资源越多。
- 通用性强:不管滚动窗口是N天,只需要调整
window_days参数,lookback_start会自动计算需要回溯的日期,适配任意月份的需求。
内容的提问来源于stack exchange,提问作者Zi Xiang
相关产品推荐
相关产品推荐

