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

基于Pandas DataFrame计算事件连续时段时长并标记首行

问题需求

我有一个包含id、条件指示器列target和时间戳列time的DataFrame,需要按id分组实现以下逻辑:

  • 当target为True时,统计连续True的时段数量(即分段数)作为时长
  • 仅在连续True时段的首行标记该时长,后续True行及所有False行均标记为0

补充说明:数据按5分钟固定分段,时长直接统计连续True的分段数,无需通过时间差计算。以B组为例:

11:00时target为True,11:05时仍为True → 11:00行duration标记为2,11:05行标记为0;
11:10时target为False,计数重置;
11:15时target为True,11:20时仍为True → 11:15行duration标记为2,11:20行标记为0;
B组最终duration值应为[2,0,0,2,0,0]

示例数据
import pandas as pd
time_test = pd.DataFrame({'id':[
    'A','B','C','A','B','C',
    'A','B','C','A','B','C',
    'A','B','C','A','B','C'],
    'target':[
        'True','True','True','False','True','True',
        'True','False','True','True','True','True',
        'False','True','False','True','False','True'],
    'time':[
        '11:00','11:00','11:00','11:05','11:05','11:05',
        '11:10','11:10','11:10','11:15','11:15','11:15',
        '11:20','11:20','11:20','11:25','11:25','11:25']})
time_test = time_test.sort_values(['id','time'])
time_test['time'] = pd.to_datetime(time_test['time'])
# 转换target为布尔值,方便后续逻辑处理
time_test['target'] = time_test['target'].map({'True': True, 'False': False})
实现步骤

步骤1:标记连续True的分组

按id分组后,用~target的累积求和来区分不同的连续True分段:

# 生成分组标识:每次遇到False,分组号递增,以此隔离不同的连续True段
time_test['group_id'] = time_test.groupby('id')['target'].apply(
    lambda x: (~x).cumsum()
)

步骤2:统计每组的连续分段数

按id和group_id分组,统计每组的行数(即连续分段的数量),并合并回原DataFrame:

# 计算每个连续True组的长度
group_length = time_test.groupby(['id', 'group_id'])['target'].count().reset_index(name='duration')
# 将统计结果匹配到原表对应行
time_test = time_test.merge(group_length, on=['id', 'group_id'], how='left')

步骤3:仅保留首行的时长值

标记每组的首行,仅在首行且target为True时保留统计的时长,其余行设为0:

# 标记当前行是否为所在分组的首行
time_test['is_first'] = time_test.groupby(['id', 'group_id']).cumcount() == 0
# 按规则设置duration值
time_test['duration'] = time_test.apply(
    lambda row: row['duration'] if row['is_first'] and row['target'] else 0,
    axis=1
)
# 清理中间辅助列
time_test = time_test.drop(['group_id', 'is_first'], axis=1)
验证结果

查看B组的输出:

print(time_test[time_test['id'] == 'B'])

输出符合预期:

id  target                time  duration
1   B    True 2023-10-17 11:00:00         2
4   B    True 2023-10-17 11:05:00         0
7   B   False 2023-10-17 11:10:00         0
10  B    True 2023-10-17 11:15:00         2
13  B    True 2023-10-17 11:20:00         0
16  B   False 2023-10-17 11:25:00         0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:35:28