如何在Pandas中回溯性生成Trend趋势状态列?
实现Trend列的解决方案
已有数据与预处理
我们已经创建了如下Pandas DataFrame,并生成了cnsIncr(连续递增计数)和cnsDecr(连续递减计数)列:
import pandas as pd import numpy as np # 创建初始DataFrame ds = {'col1' : [234,321,284,286,287,300,301,303,305,299,288,300,299,287,286,280,279,270,269,301]} df = pd.DataFrame(data=ds) # 生成连续递增/递减计数列(修正边界问题) cnsIncr = [] cnsDecr = [] col1 = np.array(df['col1']) for i in range(len(df)): cnsIncr.append(0) cnsDecr.append(0) if i > 0: if col1[i] > col1[i-1]: cnsIncr[i] = cnsIncr[i-1]+1 else: cnsIncr[i] = 0 if col1[i] < col1[i-1]: cnsDecr[i] = cnsDecr[i-1]+1 else: cnsDecr[i] = 0 df['cnsIncr'] = cnsIncr df['cnsDecr'] = cnsDecr
需求说明
需要生成Trend列,规则如下:
- 若某段连续递增序列中出现
cnsIncr≥5,则从该段的cnsIncr=0起始行到cnsIncr≥5的所有行标记为UpTrend - 若某段连续递减序列中出现
cnsDecr≥5,则从该段的cnsDecr=0起始行到cnsDecr≥5的所有行标记为DownTrend - 其余情况标记为
NoTrend
实现方法
通过标记趋势段的分组ID,筛选出符合条件的段后批量赋值,具体代码如下:
# 初始化Trend列为默认值 df['Trend'] = 'NoTrend' # 处理UpTrend # 为每个连续递增段分配唯一分组ID:cnsIncr为0时代表新段开始,分组ID累加 df['incr_group'] = (df['cnsIncr'] == 0).cumsum() # 筛选出最大cnsIncr≥5的递增分组 valid_incr_groups = df.groupby('incr_group')['cnsIncr'].max()[lambda x: x >=5].index # 为这些分组的所有行标记UpTrend df.loc[df['incr_group'].isin(valid_incr_groups), 'Trend'] = 'UpTrend' # 处理DownTrend,逻辑与UpTrend一致 df['decr_group'] = (df['cnsDecr'] == 0).cumsum() valid_decr_groups = df.groupby('decr_group')['cnsDecr'].max()[lambda x: x >=5].index df.loc[df['decr_group'].isin(valid_decr_groups), 'Trend'] = 'DownTrend' # 清理临时分组列 df.drop(['incr_group', 'decr_group'], axis=1, inplace=True) # 查看最终结果 print(df)
逻辑解释
- 分组标记:利用
cumsum()为每个连续趋势段生成唯一ID,当计数回到0时,代表新的趋势段启动,分组ID自动累加。 - 筛选有效段:按分组统计最大计数值,筛选出满足阈值(≥5)的趋势段。
- 批量赋值:将有效段内的所有行统一标记为对应趋势值。若出现极端冲突情况(同一段同时满足递增递减条件),后执行的赋值会覆盖先执行的,可根据需求调整顺序。
内容的提问来源于stack exchange,提问作者Giampaolo Levorato
相关产品推荐
相关产品推荐

