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

如何在Pandas DataFrame中分组信号的超阈值连续段

问题:如何用groupby划分DataFrame中连续超过阈值的信号分组?

我有一个包含信号数据的DataFrame,其中over_th列以布尔值标记信号是否超过阈值。想要使用groupby将信号中**连续超过阈值(即over_th为True)**的部分划分为独立分组。测试数据如下:

from io import StringIO
import pandas as pd

TESTDATA = StringIO("""date;value;over_th
2023-05-04 10:34:51.002100665;0.4;True
2023-05-04 10:34:51.007100513;0.5;True
2023-05-04 10:34:51.012100235;0.4;True
2023-05-04 10:34:51.017100083;0.3;False
2023-05-04 10:34:51.022099789;0.2;False
2023-05-04 10:35:23.610740595;0.1;False
2023-05-04 10:35:23.615740466;0.7;True
2023-05-04 10:35:23.620740227;0.8;True
2023-05-04 10:35:23.625740082;0.1;False
2023-05-04 10:35:23.630739797;0.7;True
2023-05-04 10:35:23.631;0.2;False
2023-05-04 10:35:23.632;0.8;True
2023-05-04 10:35:23.633;0.1;False
2023-05-04 10:35:23.634;0.9;True
2023-05-04 10:35:23.635;0.2;False
2023-05-04 10:35:23.630739797;0.4;True
    """)
df = pd.read_csv(TESTDATA, sep=";")

解决方案

核心思路:通过生成连续布尔区块的分组标识,再结合groupby实现分组。具体步骤如下:

1. 生成连续区块的分组键

利用shift()对比当前行与前一行的over_th值,当值发生变化时生成新的分组标识,再通过cumsum()累积求和得到唯一的分组ID:

# 生成分组标识:每遇到over_th状态变化,分组ID+1
df['group_id'] = (df['over_th'] != df['over_th'].shift()).cumsum()

这一步会给所有连续的True/False区块分配唯一ID,比如前3行True是group_id=1,接下来的False是group_id=2,再接下来的2行True是group_id=3,以此类推。

2. 筛选并分组连续超过阈值的部分

只保留over_th为True的行,然后按group_id进行分组:

# 筛选超过阈值的行,按group_id分组
groups = df[df['over_th']].groupby('group_id')

3. 验证分组结果

可以遍历分组查看结果:

for idx, (group_id, data) in enumerate(groups, 1):
    print(f"第{idx}个连续超阈值分组")
    print(data[['date', 'value']])
    print("="*30)

完整可运行代码

from io import StringIO
import pandas as pd

TESTDATA = StringIO("""date;value;over_th
2023-05-04 10:34:51.002100665;0.4;True
2023-05-04 10:34:51.007100513;0.5;True
2023-05-04 10:34:51.012100235;0.4;True
2023-05-04 10:34:51.017100083;0.3;False
2023-05-04 10:34:51.022099789;0.2;False
2023-05-04 10:35:23.610740595;0.1;False
2023-05-04 10:35:23.615740466;0.7;True
2023-05-04 10:35:23.620740227;0.8;True
2023-05-04 10:35:23.625740082;0.1;False
2023-05-04 10:35:23.630739797;0.7;True
2023-05-04 10:35:23.631;0.2;False
2023-05-04 10:35:23.632;0.8;True
2023-05-04 10:35:23.633;0.1;False
2023-05-04 10:35:23.634;0.9;True
2023-05-04 10:35:23.635;0.2;False
2023-05-04 10:35:23.630739797;0.4;True
    """)
df = pd.read_csv(TESTDATA, sep=";")

# 生成分组标识
df['group_id'] = (df['over_th'] != df['over_th'].shift()).cumsum()

# 筛选并分组连续超过阈值的行
groups = df[df['over_th']].groupby('group_id')

# 查看分组结果
for idx, (group_id, data) in enumerate(groups, 1):
    print(f"第{idx}个连续超阈值分组")
    print(data[['date', 'value']])
    print("="*30)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:59:58