如何在 Pandas 中对连续事件序列(bouts)进行分组求和

如何在 Pandas 中对连续事件序列(bouts)进行分组求和

本文介绍如何基于事件类型识别并聚合连续的“步态事件段”(stepping bouts),即对 dataframe 中相邻且类型相同的行(如 event type == 2)按 id 和日期内连续块分别求 duration 总和。

本文介绍如何基于事件类型识别并聚合连续的“步态事件段”(stepping bouts),即对 dataframe 中相邻且类型相同的行(如 event type == 2)按 id 和日期内连续块分别求 duration 总和。

在加速度计数据分析中,常需将离散的步态事件(如 Event Type == 2)按时间连续性聚合成“bouts”(行为段),再对每段的持续时间(Duration)求和——而非简单按事件类型全局分组。关键难点在于:同一 ID 同一日内可能包含多个不连续的步态段(例如:站立→步行→静坐→步行),必须区分这些独立片段。

核心思路:构建“连续段标识符”

Pandas 本身不提供原生的“连续组识别”函数,但可通过布尔掩码 + 累计求和巧妙构造分组键:

  1. 标记目标事件:用 df[‘Event Type’].eq(2) 得到布尔序列 m;
  2. 识别段边界:~m 表示非步态事件(即段间分隔点),对其按 ID 分组后使用 cumsum(),可为每个 ID 内的每一段步态事件生成唯一递增编号;
  3. 组合分组键:将 ID 与该编号联合分组,即可精准捕获每个 ID 下所有独立的步态段。

⚠️ 注意:若需进一步限定“同日内连续段”,应在分组前先添加日期列(如 Date)到 groupby 键中,避免跨日误合并。

完整实现代码

import pandas as pd

# 示例数据(含跨日及多段步态)
df = pd.DataFrame({
    'ID': [1885]*13,
    'Date': ['2021-06-29'] + ['2021-07-07']*12,
    'Event Type': [4.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0, 2.0, 2.0, 2.0, 1.0],
    'Duration': [31208.5, 1.1, 3.2, 3.5, 4.3, 3.7, 1.2, 1.1, 1.0, 3.7, 1.2, 1.1, 1.0]
})

# 步骤1:筛选步态事件(Event Type == 2)
m = df['Event Type'].eq(2)

# 步骤2:构造连续段ID(按ID分组,对非步态事件累计求和)
segment_id = (~m).groupby(df['ID']).cumsum()

# 步骤3:按ID + 段ID分组,聚合Duration总和
bouts = (df[m]
         .assign(segment_id=segment_id)
         .groupby(['ID', 'segment_id'], as_index=False)
         ['Duration'].sum()
         .drop(columns='segment_id'))

print(bouts)

输出:

     ID  Duration
0  1885      18.1
1  1885       6.0

扩展建议:支持多维度约束(如日期+ID)

若需确保“连续段”严格限定在同一日期内(防止跨日步态被错误合并),请将 Date 列加入分组逻辑:

# 更严谨的版本:按 ID + Date 联合分组识别段
m = df['Event Type'].eq(2)
# 对每个 ID-Date 组合独立计算段ID
segment_id = (~m).groupby([df['ID'], df['Date']]).cumsum()
bouts_daily = (df[m]
               .assign(segment_id=segment_id)
               .groupby(['ID', 'Date', 'segment_id'], as_index=False)
               ['Duration'].sum()
               .drop(columns='segment_id'))

小结

  • ✅ 此方法无需循环或 itertools.groupby,纯向量化,高效处理数十万行数据;
  • ✅ (~m).groupby(…).cumsum() 是识别连续段的核心技巧,适用于任意“状态切换型”分组场景;
  • ✅ 后续可轻松对 bouts 结果做统计分析,如 bouts.groupby(‘ID’)[‘Duration’].agg([‘mean’, ‘count’, ‘std’]) 计算平均步态段时长、频次等指标。

掌握该模式后,你不仅能处理步态分析,还可迁移至睡眠分期、运动周期、设备运行时段等各类“连续行为段识别”任务。

文章来自机圈观察员网,发布者:,转载请注明出处:https://www.jqgcy.com/xitongjiaocheng/126785.html

上一篇 2026-07-19 15:13
苹果突然官宣,iPhone 全系涨价!
下一篇 2026-07-19 15:17

相关推荐