如何在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
相关产品推荐
相关产品推荐

