在Pandas DataFrame中计算连续事件的持续时长
问题描述
现有如下结构的Pandas DataFrame,每行记录NTU值>2.0的5分钟间隔数据:
import pandas as pd data = { 'date': ['2021-12-02 13:30:00', '2021-12-05 01:15:00', '2021-12-05 12:10:00', '2021-12-05 13:45:00', '2021-12-05 13:50:00', '2021-12-05 18:15:00', '2021-12-05 18:20:00', '2021-12-05 18:25:00', '2021-12-05 20:05:00', '2021-12-05 20:10:00', '2021-12-05 20:40:00', '2021-12-06 09:25:00', '2021-12-23 08:35:00'], 'NTU': [3.09, 3.67, 2.12, 2.18, 2.08, 2.36, 2.36, 2.36, 2.12, 2.29, 2.17, 9.97, 5.42] } df = pd.DataFrame(data, index=[450, 1167, 1298, 1317, 1318, 1371, 1372, 1373, 1393, 1394, 1400, 1553, 6440])
当索引值连续时,代表事件持续时长超过5分钟。需找出这类事件并计算其总持续时长,期望输出如下:
date NTU duration 1318 2021-12-05 13:50:00 2.08 10 1373 2021-12-05 18:25:00 2.36 15 1394 2021-12-05 20:10:00 2.29 10
解决方案
按以下步骤处理即可得到目标结果:
- 标记连续索引分组:计算索引的差值,当差值为1时说明是连续记录,以此生成分组标签。
- 筛选有效连续事件:只保留包含至少2条记录的分组(即持续超过5分钟的事件)。
- 计算事件时长并整理结果:每个连续事件的时长为「分组内记录数×5分钟」,取每组最后一条记录的时间和NTU值,添加时长列后输出。
具体代码如下:
# 将原索引转为列,方便后续处理 df['idx'] = df.index # 计算索引差值,生成连续分组标签 df['group'] = (df['idx'].diff() != 1).cumsum() # 筛选出包含多行的分组,聚合得到结果 filtered_groups = df.groupby('group').filter(lambda x: len(x) >= 2) result = filtered_groups.groupby('group').agg( date=('date', 'last'), NTU=('NTU', 'last'), duration=('idx', lambda x: len(x)*5) ).set_index(filtered_groups['idx'].groupby('group').last()) # 移除冗余列 result = result.drop(columns='group') print(result)
执行后输出:
date NTU duration 1318 2021-12-05 13:50:00 2.08 10 1373 2021-12-05 18:25:00 2.36 15 1394 2021-12-05 20:10:00 2.29 10
代码说明
- 索引转列:把原索引转为
idx列,避免直接操作索引带来的不便。 - 分组标签生成:用
diff()计算索引的前后差值,当差值不等于1时标记为新分组起点,通过cumsum()生成连续分组的唯一ID。 - 聚合筛选:先过滤出包含至少2条记录的分组(即连续事件),再对每个分组取最后一条记录的
date和NTU,同时用「记录数×5」计算总时长,最后将分组的最后一个索引设为结果的索引,匹配期望输出格式。
内容的提问来源于stack exchange,提问作者Brian Graham
相关产品推荐
相关产品推荐

