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

如何用Pandas将含起止事件的时间序列DataFrame重塑为起止列格式?

解决方案

可以通过生成配对分组ID,结合分组聚合的方式处理这种包含异常情况的事件配对需求,具体步骤如下:

步骤1:生成配对分组ID

首先创建一个触发列,标记每个新配对组的起始位置,然后通过累计求和得到唯一的配对ID:

import pandas as pd

# 初始化原始DataFrame
df1 = pd.DataFrame({'Time': ['1:42 AM','2:30 AM','3:29 AM','4:19 AM','4:37 AM','4:59 AM','5:25 AM','5:33 AM','6:48 AM'], 
                    'Event': ['End','Start','End','Start','End','Start','Start','End','Start']})

# 创建触发列,标记新配对组的开始
trigger = pd.Series(False, index=df1.index)
# 第一行是End,单独作为一个配对组
trigger.iloc[0] = df1.iloc[0]['Event'] == 'End'
# 所有Start事件都作为新配对组的开始
trigger[1:] = df1['Event'].iloc[1:] == 'Start'
# 连续的End事件(前一行不是Start)也作为新配对组的开始
trigger[1:] |= (df1['Event'].iloc[1:] == 'End') & (df1['Event'].iloc[:-1] != 'Start')

# 生成配对ID
df1['pair_id'] = trigger.cumsum()

步骤2:分组聚合生成目标DataFrame

通过分组聚合,提取每个配对组中的Start和End时间,没有对应事件的位置填充空字符串:

# 分组聚合,处理每个配对组的Start和End
df2 = df1.groupby('pair_id').agg(
    Start=('Time', lambda x: x[df1.loc[x.index, 'Event'] == 'Start'].iloc[0] if any(df1.loc[x.index, 'Event'] == 'Start') else ''),
    End=('Time', lambda x: x[df1.loc[x.index, 'Event'] == 'End'].iloc[0] if any(df1.loc[x.index, 'Event'] == 'End') else '')
).reset_index(drop=True)

print(df2)

运行后输出结果与预期完全一致:

Start        End
0                1:42 AM
1   2:30 AM   3:29 AM
2   4:19 AM   4:37 AM
3   4:59 AM           
4   5:25 AM   5:33 AM
5   6:48 AM           

逻辑说明

  • 针对开头无前置Start的End事件:单独生成一个配对组,对应结果中Start为空、End为该时间的行
  • 针对连续的Start事件:每个Start都生成独立配对组,后续的End会匹配最近的未配对Start
  • 针对无对应End的Start事件:配对组中只有Start,End位置自动填充空字符串

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:20:30