You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为含小时值的Pandas DataFrame计算带日周期性的5小时滚动平均值?

周期性5小时滚动平均的实现方法

针对这种24小时周期的滚动平均需求,核心思路是为每个ID的时间序列补充首尾的周期数据,让常规滚动窗口能覆盖跨0点/23点的情况,具体实现如下:

实现步骤

  • 按ID分组,对每个分组单独处理:
    1. 提取分组末尾2小时(hour=22、23)和开头2小时(hour=0、1)的数据
    2. 将末尾2小时数据拼到原序列开头,开头2小时数据拼到原序列结尾,得到扩展后的序列
    3. 对扩展序列计算窗口为5、center=True的滚动平均值
    4. 截取扩展序列中间的24行,对应原有的0-23小时,即为每个ID的周期性滚动平均结果

代码示例

import numpy as np
import pandas as pd

# 构造原DataFrame(与题目代码一致)
ids = ['a', 'b', 'c']
hours = np.arange(24)
data = np.random.random((len(ids), len(hours)))
df = pd.concat([pd.DataFrame(index=[[id]*len(hours), hours], data={'value': data[ind]}) for ind, id in enumerate(ids)])
df.index.names = ['ID', 'hour']

# 定义处理单个ID分组的函数
def periodic_rolling_mean(group):
    # 提取首尾需要补充的周期数据
    tail_data = group.tail(2)
    head_data = group.head(2)
    # 拼接得到扩展序列
    extended_data = pd.concat([tail_data, group, head_data])
    # 计算滚动平均值
    extended_data['rolling_mean'] = extended_data['value'].rolling(5, center=True).mean()
    # 截取对应原24小时的结果
    return extended_data.iloc[2:-2].copy()

# 分组应用并合并结果
df_result = df.groupby('ID').apply(periodic_rolling_mean).reset_index(level=0, drop=True)

逻辑说明

扩展后的序列长度为28(24+4),使用rolling(5, center=True)时:

  • 原序列的0点对应扩展序列的第2个位置,窗口包含扩展序列前5行(22、23、0、1、2点)
  • 原序列的23点对应扩展序列的第25个位置,窗口包含扩展序列最后5行(21、22、23、0、1点)
    完美匹配周期性滚动平均的需求。

内容的提问来源于stack exchange,提问作者hm8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 23:35:27