如何按ID检测DataFrame中值首次达标并持续超阈值的行
问题描述
给定如下DataFrame:
ID Date Value 1 2010-08-01 6 1 2011-05-01 8 1 2011-12-01 7 1 2012-08-01 6 1 2013-01-01 6 1 2014-04-01 10 1 2014-08-01 8 1 2015-01-01 9 1 2016-01-01 9 1 2017-01-01 8 2 1996-01-01 5 2 1998-01-01 8 2 2010-01-01 5 2 2014-08-01 8 2 2016-01-01 8
需要针对每个ID,找出首次出现Value达到或超过阈值(此处为8),且该位置之后所有观测值都保持在阈值之上的行,期望结果如下:
ID Date Value 1 2014-04-01 10 2 2014-08-01 8
解决方案
可以通过以下步骤实现需求:
- 按
ID分组,确保每组内数据按Date排序 - 对每组从后往前检查,找到第一个满足后续所有值都≥阈值的位置
- 筛选出该位置对应的行
代码实现
import pandas as pd # 构建原始DataFrame df = pd.DataFrame({ 'ID': [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2], 'Date': ['2010-08-01','2011-05-01','2011-12-01','2012-08-01','2013-01-01','2014-04-01','2014-08-01','2015-01-01','2016-01-01','2017-01-01','1996-01-01','1998-01-01','2010-01-01','2014-08-01','2016-01-01'], 'Value': [6,8,7,6,6,10,8,9,9,8,5,8,5,8,8] }) # 阈值设定 threshold = 8 def find_target_row(group): # 确保按日期排序 group_sorted = group.sort_values('Date').reset_index(drop=True) # 从后往前遍历,找第一个位置,使得该位置及之后所有值都≥阈值 for i in range(len(group_sorted)-1, -1, -1): if (group_sorted.loc[i:, 'Value'] >= threshold).all(): return group_sorted.loc[i:i] return pd.DataFrame() # 分组应用函数,合并结果 result = df.groupby('ID').apply(find_target_row).reset_index(drop=True) print(result)
代码说明
group.sort_values('Date'):保证每组内数据按时间顺序排列,确保后续检查的准确性- 反向遍历每组数据,一旦找到某个位置开始所有值都满足≥阈值,就返回该行
- 通过
groupby.apply将每组结果合并,得到最终输出
运行后得到的结果与期望一致:
ID Date Value 0 1 2014-04-01 10 1 2 2014-08-01 8
内容的提问来源于stack exchange,提问作者Locolope
相关产品推荐
相关产品推荐

