如何在Pandas中仅针对特定日期计算滚动平均值
针对特定日期计算分组滚动平均值的优化方案
现有按Store分组计算Sales的7天、14天滚动平均值(取当前日期之前的历史数据,结果偏移至当前日期)的全量计算代码,但因数据量庞大,希望仅针对特定日期(如2022-12-31)单独计算,避免每次新增日期都全量重算。
优化思路
无需对所有日期执行滚动计算,只需针对目标日期,为每个Store提取目标日期前N天到前1天的历史数据窗口(N为7或14),直接计算该窗口的均值即可,大幅降低计算资源消耗。
代码实现
基础版本
import numpy as np import pandas as pd # 生成示例数据 ex = pd.DataFrame({ 'Date': pd.date_range('2022-10-01', '2022-12-31'), 'Store': np.random.choice(2, len(pd.date_range('2022-10-01', '2022-12-31'))), 'Sales': np.random.choice(10000, len(pd.date_range('2022-10-01', '2022-12-31'))) }) # 按Store、日期升序排序,便于区间筛选 ex.sort_values(['Store', 'Date'], ascending=True, inplace=True) ex.reset_index(drop=True, inplace=True) # 定义目标日期 target_date = pd.to_datetime('2022-12-31') # 初始化结果容器 result = { 'Date': [target_date] * ex['Store'].nunique(), 'Store': ex['Store'].unique() } # 计算7天、14天滚动均值 for days in [7, 14]: store_means = [] for store in ex['Store'].unique(): # 筛选目标日期前days天至前1天的数据 window_mask = (ex['Store'] == store) & \ (ex['Date'] >= target_date - pd.Timedelta(days=days)) & \ (ex['Date'] <= target_date - pd.Timedelta(days=1)) window_sales = ex.loc[window_mask, 'Sales'] # 数据量足够时计算均值,否则返回NaN store_means.append(window_sales.mean() if len(window_sales) == days else np.nan) result[f'Sales_mean_{days}_days'] = store_means # 转换为结果DataFrame target_result = pd.DataFrame(result) print(target_result)
简洁版(用groupby简化)
# 定义计算单个Store目标均值的函数 def get_target_window_mean(group, target_date, days): window_start = target_date - pd.Timedelta(days=days) window_end = target_date - pd.Timedelta(days=1) window_data = group[(group['Date'] >= window_start) & (group['Date'] <= window_end)]['Sales'] return window_data.mean() if len(window_data) == days else np.nan # 分组计算目标日期的滚动均值 target_result = ex.groupby('Store').apply( lambda g: pd.Series({ 'Date': target_date, 'Sales_mean_7_days': get_target_window_mean(g, target_date, 7), 'Sales_mean_14_days': get_target_window_mean(g, target_date, 14) }) ).reset_index()
说明
- 若需处理多个目标日期,只需将目标日期放入列表循环执行即可
- 若要将结果合并回原DataFrame,可使用
pd.merge(ex, target_result, on=['Store', 'Date'], how='left')实现 - 代码中判断窗口数据量是否等于N,可根据实际需求调整(比如允许少于N天的数据计算均值)
内容的提问来源于stack exchange,提问作者RodiX
相关产品推荐
相关产品推荐

