如何在DataFrame中计算3天滚动窗口的统计数据?
用Pandas实现3天滚动窗口的贡献统计
步骤说明与代码实现
首先明确两个目标列的定义:
focal_user_contribution_3day:当前行用户在以当前日期为终点的3天时间窗口内的所有贡献总和average_contribution_3day:该3天窗口内,所有唯一用户的各自贡献总和的平均值(总贡献和除以窗口内的唯一用户数)
1. 准备示例数据
先模拟符合描述的数据集:
import pandas as pd # 构造示例数据:用户、日期、当日贡献 data = { 'user_id': [1, 2, 3, 1, 2, 3, 3, 1, 2], 'date': [ '2023-01-25', '2023-01-25', '2023-01-25', '2023-01-26', '2023-01-26', '2023-01-26', '2023-01-27', '2023-01-28', '2023-01-28' ], 'contribution': [1, 3, 65, 0, 0, 7, 0, 0, 0] } df = pd.DataFrame(data) # 将日期列转换为datetime类型(滚动窗口的基础) df['date'] = pd.to_datetime(df['date'])
2. 计算focal_user_contribution_3day
通过groupby按用户分组,再使用时间滚动窗口求和:
# 对每个用户,计算其在3天窗口内的累计贡献 df['focal_user_contribution_3day'] = df.groupby('user_id')['contribution'] \ .rolling(window='3D', on='date') \ .sum() \ .reset_index(level=0, drop=True)
window='3D'表示时间跨度为3天的滚动窗口,包含当前日期及过去72小时内的所有记录reset_index用于将分组后的结果合并回原DataFrame
3. 计算average_contribution_3day
先统计窗口内所有用户的贡献总和,再除以窗口内的唯一用户数:
# 生成用户-日期的完整网格,填充无贡献日期的0值 all_dates = df['date'].unique() all_users = df['user_id'].unique() date_user_grid = pd.MultiIndex.from_product( [all_dates, all_users], names=['date', 'user_id'] ).to_frame(index=False) full_df = date_user_grid.merge(df, on=['date', 'user_id'], how='left').fillna({'contribution': 0}) # 计算每个用户在3天窗口内的贡献总和 full_df['user_3day_total'] = full_df.groupby('user_id')['contribution'] \ .rolling(window='3D', on='date') \ .sum() \ .reset_index(level=0, drop=True) # 按日期聚合,计算窗口内的总贡献和用户数,进而得到平均值 daily_stats = full_df.groupby('date').agg( total_contribution_sum=('user_3day_total', 'sum'), unique_user_count=('user_id', 'nunique') ) daily_stats['average_contribution_3day'] = daily_stats['total_contribution_sum'] / daily_stats['unique_user_count'] # 将结果合并回原DataFrame df = df.merge(daily_stats[['average_contribution_3day']], on='date', how='left')
4. 验证结果
以你提到的索引7的行(日期2023-01-28,用户1)为例:
focal_user_contribution_3day:用户1在25-28日的贡献总和为1(仅25日有贡献)average_contribution_3day:窗口内3个用户的贡献总和为1+3+(65+7)=76,除以3得到约26.33,与示例一致
效率说明
以上方法均使用Pandas内置的矢量化操作和滚动窗口函数,避免循环遍历,可高效处理大规模数据集。
内容的提问来源于stack exchange,提问作者Houhouhia
相关产品推荐
相关产品推荐

