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

如何在Pandas的groupby分类分组内执行时间滚动窗口聚合?

解决Pandas分组内时间滚动窗口聚合并保留原列的问题

我明白你的需求啦——想要在分类变量cat的每个分组内,基于时间列t对数值列val执行滚动窗口聚合,同时保留原表的所有列,只新增一列聚合结果对吧?咱们一步步来搞定这个问题。

首先先补全你提供的示例数据生成代码(原代码有截断),方便后续测试:

import random
import numpy as np
import pandas as pd

N = 100
np.random.seed(0)
random.seed(0)

# 生成带时间、分类、数值的测试数据
timestamps = pd.date_range(start='2018-01-01', periods=N, freq='H')
df = pd.DataFrame({
    "t": timestamps,
    "cat": np.random.choice(["A", "B", "C"], size=N),
    "val": np.random.randn(N)
})

核心实现方案

我们可以利用groupby结合rolling来实现分组内的时间窗口聚合,关键是让聚合结果和原表索引对齐,这样就能直接新增一列而不丢失原有数据。这里以2小时时间窗口内的val均值为例:

# 定义滚动时间窗口大小(支持'H'小时、'D'天、'min'分钟等单位)
window_size = '2H'

# 分组执行滚动聚合,并合并回原表
df['rolling_val_mean'] = df.groupby('cat').apply(
    lambda group: group.set_index('t')['val'].rolling(window=window_size).mean()
).reset_index(level=0, drop=True)

代码解释

  • df.groupby('cat'):按分类变量cat拆分数据,每个分组单独处理
  • lambda group: group.set_index('t')['val'].rolling(window=window_size).mean():对每个分组,先把时间列t设为索引(时间滚动窗口必须基于时间索引),然后对val列执行滚动窗口均值计算
  • reset_index(level=0, drop=True):去掉分组产生的cat索引层级,让聚合结果的索引和原表完全匹配,这样就能直接赋值为新列

自定义调整

你可以根据需求灵活修改这段代码:

  • 更换聚合函数:把.mean()换成.sum()、.max()、.min()甚至自定义聚合函数(比如.apply(lambda x: x.std()))
  • 调整窗口类型:如果需要固定行数的窗口而非时间窗口,把window='2H'换成数字,比如window=3(代表包含当前行在内的最近3行)
  • 窗口闭合方式:默认窗口包含当前时间,若需调整可加closed参数,比如rolling(window='2H', closed='left')表示窗口不包含当前时间点
  • 时间列预处理:如果你的t列还不是datetime格式,先执行df['t'] = pd.to_datetime(df['t'])转换

验证结果

你可以查看某个分组的结果,确认聚合是否正确:

print(df[df['cat'] == 'A'].head())

输出示例:

t cat       val  rolling_val_mean
0 2018-01-01 00:00:00   A  1.764052          1.764052
3 2018-01-01 03:00:00   A  0.978738          0.978738
4 2018-01-01 04:00:00   A  2.240893          2.240893
6 2018-01-01 06:00:00   A -0.977278         -0.977278
7 2018-01-01 07:00:00   A  0.950088          0.950088

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:13:15