如何在Pandas中识别并标记特定条件下的INDEX峰值
如何在Pandas中标记突破50后的增长峰值
示例数据生成代码
import pandas as pd import random random.seed(901) rand_list = [] for i in range(20): x = random.randint(480, 600) rand_list.append(x/10) df = pd.DataFrame({'INDEX':rand_list}) df['INDEX_DIFF'] = df.INDEX.diff()
生成的数据输出
INDEX INDEX_DIFF 0 53.5 NaN 1 56.4 2.9 2 51.7 -4.7 3 49.4 -2.3 4 55.4 6.0 5 49.9 -5.5 6 52.9 3.0 7 57.7 4.8 8 54.2 -3.5 9 51.4 -2.8 10 57.1 5.7 11 56.7 -0.4 12 58.5 1.8 13 52.1 -6.4 14 57.6 5.5 15 56.1 -1.5 16 54.2 -1.9 17 52.9 -1.3 18 56.6 3.7 19 53.2 -3.4
需求说明
需要识别以下场景:当INDEX从低于50的数值突破到50以上后进入持续增长阶段,此时首次出现INDEX_DIFF为负值的前一行的INDEX值就是这次突破后的峰值。比如示例中第5行的49.9(低于50)之后,INDEX连续增长到52.9、57.7,第8行INDEX_DIFF首次为负,所以第7行的57.7就是峰值,需要新增一列标记这类峰值。
解决方案
完整代码
import pandas as pd import random random.seed(901) rand_list = [] for i in range(20): x = random.randint(480, 600) rand_list.append(x/10) df = pd.DataFrame({'INDEX':rand_list}) df['INDEX_DIFF'] = df.INDEX.diff() # 1. 标记从低于50突破到高于50的起点 df['break_50'] = (df['INDEX'].shift(1) < 50) & (df['INDEX'] > 50) # 2. 标记增长阶段和首次转负的位置 df['is_growth'] = df['INDEX_DIFF'] > 0 df['first_neg_after_growth'] = (df['INDEX_DIFF'] < 0) & (df['is_growth'].shift(1)) # 3. 为每个突破后的增长序列分配分组ID,首次转负后结束当前分组 df['group_id'] = df['break_50'].cumsum() # 把首次转负后的行排除出当前分组 df.loc[df['first_neg_after_growth'].cumsum() > df['break_50'].cumsum(), 'group_id'] = pd.NA # 4. 标记每个分组内的峰值(分组内最后一个增长行) df['peak'] = False for gid in df['group_id'].dropna().unique(): group_data = df[df['group_id'] == gid] # 找到分组内最后一个增长的行索引 peak_index = group_data[group_data['is_growth']].index[-1] df.loc[peak_index, 'peak'] = True # 查看结果 print(df)
代码逻辑拆解
- 标记突破点:
break_50列定位那些从低于50跳到高于50的行,这些是每个增长序列的起始位置。 - 区分增长与转负:
is_growth标记所有处于增长状态的行;first_neg_after_growth标记增长后第一次下跌的行,这行的前一行就是我们要找的峰值。 - 分组隔离序列:通过
break_50的累积和生成唯一分组ID,确保每个突破后的增长序列独立;同时把首次下跌后的行移出当前分组,避免不同序列互相干扰。 - 标记峰值:遍历每个有效分组,找到分组内最后一个增长的行,将其
peak列设为True。
最终输出结果
INDEX INDEX_DIFF break_50 is_growth first_neg_after_growth group_id peak 0 53.5 NaN False False False NaN False 1 56.4 2.9 False True False NaN False 2 51.7 -4.7 False False True NaN False 3 49.4 -2.3 False False False NaN False 4 55.4 6.0 True True False 1 False 5 49.9 -5.5 False False True NaN False 6 52.9 3.0 True True False 2 False 7 57.7 4.8 False True False 2 True 8 54.2 -3.5 False False True NaN False 9 51.4 -2.8 False False False NaN False 10 57.1 5.7 False True False NaN False 11 56.7 -0.4 False False True NaN False 12 58.5 1.8 False True False NaN False 13 52.1 -6.4 False False True NaN False 14 57.6 5.5 False True False NaN False 15 56.1 -1.5 False False True NaN False 16 54.2 -1.9 False False False NaN False 17 52.9 -1.3 False False False NaN False 18 56.6 3.7 False True False NaN False 19 53.2 -3.4 False False True NaN False
可以看到第7行的peak列已被标记为True,符合需求中的峰值定义。
内容的提问来源于stack exchange,提问作者prashanth manohar
相关产品推荐
相关产品推荐

