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

Pandas按小时聚合数据时保留实际起止时间的方法咨询

按小时分组聚合时保留实际起止时间的Pandas解决方案

问题描述

我有一个包含timestamp(时间戳)和数值的DataFrame,示例代码如下:

import pandas as pd
import numpy as np

time_list = ['2020-04-22 13:29:00+00:00','2020-04-22 13:31:00+00:00','2020-04-22 13:32:00+00:00','2020-04-22 13:33:00+00:00','2020-04-22 13:34:00+00:00','2020-04-22 13:35:00+00:00','2020-04-22 13:36:00+00:00','2020-04-22 13:54:00+00:00','2020-04-22 13:55:00+00:00','2020-04-22 13:56:00+00:00','2020-04-22 13:57:00+00:00','2020-04-22 13:58:00+00:00','2020-04-22 13:59:00+00:00','2020-04-22 14:00:00+00:00','2020-04-22 14:01:00+00:00','2020-04-22 14:02:00+00:00','2020-04-22 14:03:00+00:00','2020-04-22 14:04:00+00:00','2020-04-22 14:05:00+00:00','2020-04-22 14:06:00+00:00','2020-04-22 14:49:00+00:00','2020-04-22 14:50:00+00:00','2020-04-22 14:51:00+00:00','2020-04-22 14:52:00+00:00','2020-04-22 14:53:00+00:00','2020-04-22 14:54:00+00:00','2020-04-22 14:55:00+00:00','2020-04-22 14:56:00+00:00','2020-04-22 14:57:00+00:00','2020-04-22 14:58:00+00:00','2020-04-22 14:59:00+00:00','2020-04-22 15:00:00+00:00','2020-04-22 15:01:00+00:00','2020-04-22 15:02:00+00:00','2020-04-22 15:24:00+00:00','2020-04-22 15:25:00+00:00','2020-04-22 15:26:00+00:00','2020-04-22 15:27:00+00:00','2020-04-22 15:28:00+00:00','2020-04-22 15:29:00+00:00','2020-04-22 15:36:00+00:00']
df = pd.DataFrame(time_list)
df.columns = ['timestamp']
df['rand']=np.random.randint(0, 100, df.shape[0])
df.timestamp = pd.to_datetime(df.timestamp)
df.set_index('timestamp', inplace=True)

使用resample按小时聚合求和:

agg_dict = {'rand': 'sum'}
dfr = df.resample('1H').agg(agg_dict)

但这种方式会丢失每个时段的实际起止时间:比如第一个时段实际从13:29开始,聚合结果却标记为13:00(易被误认为覆盖13:00-14:00全时段);最后一个时段实际到15:36结束,结果仅显示15:00,容易让人误以为数据覆盖到15:59。需要一种能保留每个小时分组实际起止时间的方法,且不想自行编写复杂代码。


解决方案

方法1:扩展resample的聚合逻辑

Pandas没有直接的内置函数实现该需求,但可以通过自定义聚合函数,在resample的基础上同时计算每个时段的实际起止时间,代码量极小:

def agg_with_time(group):
    return pd.Series({
        'rand_sum': group['rand'].sum(),
        'actual_start': group.index.min(),
        'actual_end': group.index.max()
    })

# 按小时分组并应用自定义聚合
result = df.resample('1H').apply(agg_with_time).dropna()

说明:

  • resample('1H')依然负责按自然小时分组,保证分组逻辑正确
  • 自定义函数agg_with_time对每个分组计算三个值:数值总和、分组内最早时间(实际开始)、分组内最晚时间(实际结束)
  • dropna()用于过滤没有数据的小时时段

输出示例:

timestamprand_sumactual_startactual_end
2020-04-22 13:00:006422020-04-22 13:29:00+00:002020-04-22 13:59:00+00:00
2020-04-22 14:00:0010252020-04-22 14:00:00+00:002020-04-22 14:59:00+00:00
2020-04-22 15:00:005172020-04-22 15:00:00+00:002020-04-22 15:36:00+00:00

方法2:使用groupby配合小时提取

如果更习惯常规groupby语法,也可以通过提取日期+小时的分组键来实现:

# 生成日期+小时的分组键
df['hour_group'] = df.index.floor('H')

# 分组聚合
result = df.groupby('hour_group').agg(
    rand_sum=('rand', 'sum'),
    actual_start=('timestamp', 'min'),
    actual_end=('timestamp', 'max')
).reset_index().rename(columns={'hour_group': 'hour_start'})

这个方法同样能清晰展示每个时段的实际数据范围,结果结构与方法1一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:20:31