Pandas按连续30分钟时间间隔分组异常问题求助
问题描述
原始DataFrame结构:
| date | week | id |
|---|---|---|
| 20/07/21 12:46:00 | 1 | d1 |
| 20/07/21 12:56:00 | 1 | d1 |
| 20/07/21 13:09:00 | 1 | d1 |
| 20/07/21 14:11:00 | 1 | d1 |
| 20/07/21 14:42:00 | 1 | d1 |
需求:按连续30分钟时间间隔分组——若连续两行的时间差超过30分钟,则分为不同组。期望输出:
| week | id | min_date | max_date |
|---|---|---|---|
| 1 | d1 | 20/07/21 12:46:00 | 20/07/21 13:09:00 |
| 1 | d1 | 20/07/21 14:11:00 | 20/07/21 14:11:00 |
| 1 | d1 | 20/07/21 14:42:00 | 20/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分钟则分组”的需求。
正确实现步骤
- 确保
date列是datetime类型(若原始是字符串需转换) - 计算相邻行的时间差
- 根据时间差是否超过30分钟,生成动态分组标识
- 按
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
相关产品推荐
相关产品推荐

