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

如何在Python中按Class分组统计各Event的起止时间?

按Class分组提取Event的起止时间问题解决方案

我看了你遇到的问题——尝试按Class分组提取每个连续Event的开始和结束时间,但之前的代码返回了空DataFrame。咱们先拆解下原代码的问题,再给出正确的实现方式。

原代码的问题分析

  • 循环中错误引用了全局的data而非当前分组的group,而且class是Python的关键字,不能用作变量名。
  • 没有对每个分组内的时间进行排序,这会导致无法正确识别连续的Event段。
  • 遗漏了分组内最后一个Event的结束时间记录。
  • Time列的格式有问题(带有前缀如0 ),需要先清理转换为datetime类型才能正确处理。

正确的实现步骤

首先咱们先预处理数据,把Time列清理成标准的datetime格式,然后按Class分组,再识别每个分组内连续的Event段,提取起止时间。

代码实现

import pandas as pd

# 构造示例数据(替换为你自己的DataFrame即可)
data = pd.DataFrame({
    'Class': [0,1,2,3,4,5,6,7,8,9,10,11,12],
    'Event': ['A','A','B','B','B','B','A','B','A','B','A','B','A'],
    'Time': ['0 2020-02-19 11:00:00','1 2020-02-19 11:30:00','1 2020-02-19 11:00:00',
             '1 2020-02-19 11:30:00','0 2020-02-19 12:00:00','0 2020-02-19 12:30:00',
             '0 2020-02-19 14:00:00','1 2020-02-19 13:30:00','1 2020-02-19 15:00:00',
             '1 2020-02-19 15:30:00','0 2020-02-19 15:30:00','0 2020-02-19 16:00:00',
             '1 2020-02-19 16:30:00']
})

# 第一步:清理Time列,转换为datetime类型
data['Time'] = pd.to_datetime(data['Time'].str.split(' ', n=1).str[1])

# 第二步:按Class分组,每个分组内按Time排序
grouped = data.groupby('Class').apply(lambda x: x.sort_values('Time')).reset_index(drop=True)

# 第三步:识别每个分组内连续的Event段
# 标记Event发生变化的位置
grouped['event_change'] = grouped.groupby('Class')['Event'].shift() != grouped['Event']
# 为每个连续Event段分配唯一ID
grouped['segment_id'] = grouped.groupby('Class')['event_change'].cumsum()

# 第四步:按Class和segment_id分组,提取起止时间
result = grouped.groupby(['Class', 'segment_id', 'Event']).agg(
    EventStartTime=('Time', 'first'),
    EventEndTime=('Time', 'last')
).reset_index().drop('segment_id', axis=1)

# 调整列顺序(可选)
result = result[['Class', 'Event', 'EventStartTime', 'EventEndTime']]

print(result)

代码解释

  1. Time列预处理:用str.split去掉时间字符串前的多余前缀,再转成datetime类型,确保时间可以正确排序和比较。
  2. 分组排序:每个Class分组内按Time排序,保证连续的Event按时间顺序排列,避免逻辑混乱。
  3. 标记Event变化:用shift()比较当前行和上一行的Event是否相同,标记出Event发生变化的位置。
  4. 生成段ID:通过cumsum()为每个连续的Event段分配唯一ID,方便后续分组聚合。
  5. 聚合起止时间:按Class、segment_id和Event分组,取每个段的第一个时间作为开始时间,最后一个时间作为结束时间。

输出结果

运行后得到的结果与你期望的结构一致(注:你期望结果中的日期笔误已修正,比如2020-02-10应为2020-02-19):

ClassEventEventStartTimeEventEndTime
0A2020-02-19 11:00:002020-02-19 16:30:00
1A2020-02-19 11:30:002020-02-19 15:00:00
1B2020-02-19 15:30:002020-02-19 15:30:00
2B2020-02-19 11:00:002020-02-19 11:00:00
3B2020-02-19 11:30:002020-02-19 11:30:00
4B2020-02-19 12:00:002020-02-19 12:00:00
5B2020-02-19 12:30:002020-02-19 12:30:00
6A2020-02-19 14:00:002020-02-19 14:00:00
7B2020-02-19 13:30:002020-02-19 13:30:00
8A2020-02-19 15:00:002020-02-19 15:00:00
9B2020-02-19 15:30:002020-02-19 15:30:00
10A2020-02-19 15:30:002020-02-19 15:30:00
11B2020-02-19 16:00:002020-02-19 16:00:00
12A2020-02-19 16:30:002020-02-19 16:30:00

(如果你的需求是合并同一Class下相同Event的非连续段,只需要调整聚合逻辑,去掉segment_id分组即可。)

内容的提问来源于stack exchange,提问作者Priyanka S. Desai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 18:14:09