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

如何用Pandas按Id和小时分组聚合并补全缺失时段?

按Id分组聚合小时数据并保留空时段解决方案

问题描述

我有一个包含Id、Date、Number列的DataFrame,需要按Id分组并按小时对Number进行聚合,同时要保留每个Id的最小与最大datetime之间无数据的时段。

示例数据集:

Id    Date                    Number
1     01-01-2022 00:00:00     1
1     01-01-2022 00:25:00     3
1     01-01-2022 01:00:10     1
2     01-01-2022 00:00:01     4
2     01-01-2022 03:01:01     2

期望结果:

Id    Date                    Number
1     01-01-2022 00:00:00     4
1     01-01-2022 01:00:00     1
2     01-01-2022 00:00:00     4
2     01-01-2022 01:00:00     NaN
2     01-01-2022 02:00:00     NaN
2     01-01-2022 03:00:00     2

尝试了以下代码但结果缺失空时段:

agg = {'Number': 'sum'} #example
data = data.groupby(['Id', pd.Grouper(key='Date', freq='1H')]).agg(agg)

问题原因

直接使用groupby + pd.Grouper只会保留原数据中存在数据的小时区间,不会自动填充每个Id的最小到最大时间范围内的所有小时节点。要保留空时段,必须先为每个Id生成完整的小时时间序列,再与聚合后的数据合并。


解决方案

步骤1:转换日期格式

首先确保Date列是datetime类型:

import pandas as pd

# 转换Date列为datetime类型
data['Date'] = pd.to_datetime(data['Date'], format='%d-%m-%Y %H:%M:%S')

步骤2:生成每个Id的完整小时时间序列

为每个Id生成从最小日期到最大日期的所有小时节点:

def generate_hour_range(group):
    # 取该Id的最小和最大日期,并向下取整到小时
    start = group['Date'].min().floor('H')
    end = group['Date'].max().floor('H')
    # 生成小时级时间序列
    hours = pd.date_range(start=start, end=end, freq='1H')
    return pd.DataFrame({'Date': hours, 'Id': group['Id'].iloc[0]})

# 按Id分组生成完整时间序列
full_hours = data.groupby('Id').apply(generate_hour_range).reset_index(drop=True)

步骤3:聚合原数据并合并

将原数据按小时聚合后,与完整时间序列合并,自动填充空时段的NaN:

# 按Id和小时聚合Number(求和)
agg_data = data.groupby(['Id', pd.Grouper(key='Date', freq='1H')])['Number'].sum().reset_index()

# 左连接完整时间序列和聚合数据,保留所有小时节点
result = pd.merge(full_hours, agg_data, on=['Id', 'Date'], how='left')

查看最终结果

print(result)

运行后即可得到包含空时段的期望结果,无数据的小时Number字段会显示为NaN。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 06:10:43