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

Pandas按连续30分钟时间间隔分组异常问题求助

问题描述

原始DataFrame结构:

dateweekid
20/07/21 12:46:001d1
20/07/21 12:56:001d1
20/07/21 13:09:001d1
20/07/21 14:11:001d1
20/07/21 14:42:001d1

需求:按连续30分钟时间间隔分组——若连续两行的时间差超过30分钟,则分为不同组。期望输出:

weekidmin_datemax_date
1d120/07/21 12:46:0020/07/21 13:09:00
1d120/07/21 14:11:0020/07/21 14:11:00
1d120/07/21 14:42:0020/07/21 14:42:00

原实现代码:

x=df.groupby(['id','week', pd.Grouper(key='date', freq='30min',origin="start")]).agg({'date':[np.min, np.max]})

问题:分组器未正常工作。例如20/07/21 07:27:00与20/07/21 08:34:00间隔超1小时,却被错误归为同一组,不符合期望。

解决方案

核心问题分析

pd.Grouper(freq='30min')是固定时间窗口分组,会按预设的30分钟区间(如12:00-12:30、12:30-13:00)分配行,完全不考虑相邻行之间的实际时间间隔,因此无法满足“连续行时间差超过30分钟则分组”的需求。

正确实现步骤

  1. 确保date列是datetime类型(若原始是字符串需转换)
  2. 计算相邻行的时间差
  3. 根据时间差是否超过30分钟,生成动态分组标识
  4. 按id、week和分组标识聚合,得到每组的最小/最大时间

代码实现

import pandas as pd
import numpy as np

# 1. 转换date列为datetime类型(若未转换)
df['date'] = pd.to_datetime(df['date'], format='%y/%m/%d %H:%M:%S')

# 2. 计算相邻行的时间差,第一行填充0
df['time_diff'] = df['date'].diff().fillna(pd.Timedelta(minutes=0))

# 3. 生成分组标识:时间差超过30分钟则新建一组
df['group_key'] = (df['time_diff'] > pd.Timedelta(minutes=30)).cumsum()

# 4. 分组聚合并整理列名
result = df.groupby(['id', 'week', 'group_key']).agg(
    min_date=('date', 'min'),
    max_date=('date', 'max')
).reset_index().drop('group_key', axis=1)

# 格式化时间列(可选,匹配原始格式)
result['min_date'] = result['min_date'].dt.strftime('%y/%m/%d %H:%M:%S')
result['max_date'] = result['max_date'].dt.strftime('%y/%m/%d %H:%M:%S')

print(result)

代码说明

  • diff()计算当前行与上一行的时间差,第一行无前置行,用fillna补0
  • (time_diff > pd.Timedelta(minutes=30)).cumsum():当时间差超过30分钟时,布尔值为True(即1),累加后会生成递增的分组ID,实现动态分组
  • 最后聚合时去掉临时的group_key,得到符合需求的输出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:15:41