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

如何为带时间戳的DataFrame设置自定义步长的滚动窗口?

按整日历日步进的多日窗口处理方案

你的核心需求是:窗口包含连续N个完整日历日的所有小时数据,且窗口按整日历日步进(而非小时级滑动),pandas.DataFrame.rolling的默认时间窗口是滑动式的,确实不直接适配,但不需要完全自定义窗口函数,以下两种方案可以解决:


方案1:手动生成窗口边界,按需筛选计算

这种方式灵活性最高,适合需要保留小时级原始数据的场景:

  1. 提取时间列的日期部分,获取所有唯一日历日
  2. 遍历生成每个N天窗口的起始/结束日期
  3. 筛选对应日期范围的数据,执行自定义操作

示例代码(以2天窗口为例):

import pandas as pd

# 假设你的DataFrame是df,复合索引为(time, node)
df = df.reset_index()  # 将索引转为列,方便日期筛选

# 获取所有唯一的日历日
unique_days = df['time'].dt.date.unique()

window_output = []
# 遍历生成每个2天窗口
for idx in range(len(unique_days) - 1):
    start_day = unique_days[idx]
    end_day = unique_days[idx + 1]
    # 筛选窗口内的所有小时数据:从start_day 00:00到end_day 23:59
    window_mask = (df['time'].dt.date >= start_day) & (df['time'].dt.date <= end_day)
    window_df = df[window_mask]
    
    # 这里替换为你的实际操作,比如按node计算统计值
    node_stats = window_df.groupby('node').agg(
        avg_value=('value', 'mean'),
        total_count=('value', 'count')
    )
    # 给结果添加窗口标识
    node_stats['window_start'] = pd.Timestamp(start_day)
    node_stats['window_end'] = pd.Timestamp(end_day) + pd.Timedelta(hours=23, minutes=59, seconds=59)
    
    window_output.append(node_stats)

# 合并所有窗口结果
final_result = pd.concat(window_output).reset_index()

方案2:结合resample与rolling实现

如果你的操作可以先按天聚合,再滑动窗口,这种写法更简洁:

# 先将数据按node和天分组,计算每日聚合值(根据需求调整聚合逻辑)
daily_agg = df.reset_index().groupby(
    ['node', pd.Grouper(key='time', freq='D')]
).agg(total_value=('value', 'sum')).reset_index()

# 对每个node,使用rolling(window=2)实现2天滑动窗口计算
sliding_result = daily_agg.groupby('node').rolling(
    window=2, on='time'
).agg(rolling_total=('total_value', 'sum')).reset_index()

总结

两种方案都无需完全自定义窗口函数:

  • 方案1适合需要保留小时级细节、执行复杂窗口操作的场景
  • 方案2适合先按天聚合再滑动的场景,代码更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:45:32