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

如何在Polars中按日、小时分组执行31天滚动均值计算?

按小时计算过去31天Amount均值的问题分析与解决方案

问题背景

  • 数据集包含列:Node、Time(小时间隔)、date(对应Time的日期)、Hour、Amount,每个Node每小时仅一条数据
  • 需求:每日每个Hour,计算该小时过去31天的Amount均值
  • 尝试代码:
df.rolling('Time', period='31d', group_by=['date', 'Hour']).agg(pl.col('Amount').mean())
  • 异常:结果行数与原数据集一致,未得到每日每小时一行的预期输出

原代码计算逻辑解析

这段代码的核心问题在于分组逻辑和滚动窗口的匹配错误:

  • group_by=['date', 'Hour']会将数据拆分为【日期+小时】的分组,但原数据中每个Node每小时一条,所以每个分组实际是【日期+小时+Node】的单条数据
  • 对单条数据做31天滚动窗口计算,只能得到该条数据自身的均值,最终所有分组结果拼接后,行数自然和原数据完全一致
  • 本质是按【日期+小时+Node】的细粒度计算,而非需求的【日期+小时】聚合粒度

正确实现方法

场景1:按每日每小时(合并所有Node)计算过去31天均值

如果需要将同一小时所有Node的Amount先聚合,再计算过去31天均值:

# 1. 先聚合得到每日每小时的总Amount(可根据业务调整聚合方式,比如mean)
daily_hourly_agg = df.group_by(['date', 'Hour']).agg(
    pl.col('Amount').sum().alias('DailyHourlyTotal')
).sort('date')  # 确保时间序列有序

# 2. 按Hour分组,做31天滚动窗口均值计算
final_result = daily_hourly_agg.group_by('Hour').rolling(
    index_column='date',
    period='31d'
).agg(
    pl.col('DailyHourlyTotal').mean().alias('Past31dAvg')
)

场景2:按每个Node的每日每小时计算过去31天均值

如果需要保留Node维度,计算每个Node下各小时的过去31天均值:

final_result = df.group_by(['Node', 'Hour']).rolling(
    index_column='date',
    period='31d'
).agg(
    pl.col('Amount').mean().alias('Past31dAvg')
).sort(['Node', 'Hour', 'date'])

逻辑说明

  • 先按Hour(或Node+Hour)分组,确保每个分组内是同一小时(或同一Node+小时)的全日期数据
  • 基于date列做31天滚动窗口,计算窗口内Amount的均值,最终结果即为每日每小时(或Node+每日每小时)一行的结构

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 11:48:13