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

如何在Pandas中按Category分组获取当前时间前n天同时刻数据

问题描述

我有如下时间序列数据,希望先按category分组,之后在每个分组内,获取当前时间前n天(此处以n=1为例)同一时刻对应的数据。

如果不分组,我可以用data.rolling(window='1D', closed='both', on='time').apply(lambda x:x[0])实现,但分组后不知道怎么操作,请问该如何实现?

示例数据

import pandas as pd
data1 = {'time': ['2020-01-01 00:00:00', '2020-01-01 04:00:00', '2020-01-01 08:00:00', '2020-01-01 12:00:00', '2020-01-01 16:00:00', '2020-01-01 20:00:00', '2020-01-02 00:00:00', '2020-01-02 04:00:00', '2020-01-02 08:00:00', '2020-01-02 12:00:00', '2020-01-02 16:00:00', '2020-01-02 20:00:00', '2020-01-03 00:00:00', '2020-01-03 04:00:00', '2020-01-03 08:00:00', '2020-01-03 12:00:00', '2020-01-03 16:00:00', '2020-01-03 20:00:00', '2020-01-04 00:00:00', '2020-01-04 04:00:00'], 'category': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c'], 'nums': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]}
df = pd.DataFrame(data1)

解决方案

方法1:分组后通过时间特征匹配

先提取时间的时分部分作为同一时刻的匹配依据,再在分组内关联前n天的对应数据:

# 转换time列为datetime类型
df['time'] = pd.to_datetime(df['time'])
# 提取时分信息,用于匹配同一时刻
df['time_of_day'] = df['time'].dt.time

def extract_prev_day_data(group, n=1):
    # 计算当前时间前n天的时间点
    group['prev_day_time'] = group['time'] - pd.Timedelta(days=n)
    # 合并分组内数据,匹配前n天同一时刻的记录
    merged = pd.merge(
        group,
        group,
        left_on=['category', 'prev_day_time', 'time_of_day'],
        right_on=['category', 'time', 'time_of_day'],
        suffixes=('', '_prev')
    )
    return merged[['time', 'category', 'nums', 'nums_prev']]

# 分组应用函数
result = df.groupby('category', group_keys=False).apply(extract_prev_day_data, n=1)
print(result)

方法2:分组后直接使用rolling窗口

保留你原本的rolling思路,只需在分组后调用即可,注意先对分组内的时间排序:

df['time'] = pd.to_datetime(df['time'])
# 按分组和时间排序,确保窗口计算正确
df = df.sort_values(['category', 'time'])

# 分组后应用rolling窗口,取窗口内第一条数据(前1天同一时刻的值)
df['nums_prev'] = df.groupby('category').rolling(
    window='1D',
    closed='both',
    on='time'
)['nums'].apply(lambda x: x.iloc[0] if len(x) >= 2 else None).reset_index(level=0, drop=True)

print(df)

方法3:固定时间间隔下使用shift偏移

如果数据是固定间隔采样(比如示例中每4小时一条,1天共6条),可以直接通过shift按行数偏移:

df['time'] = pd.to_datetime(df['time'])
df = df.sort_values(['category', 'time'])

# 计算1天对应的行数:24小时 / 4小时间隔 = 6行
n_days = 1
shift_rows = n_days * 6

# 分组后偏移对应行数
df['nums_prev'] = df.groupby('category')['nums'].shift(shift_rows)

print(df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 11:05:26