基于Ratio列连续增减规则生成Signal列的技术实现问询
为DataFrame生成符合规则的Signal列
原始DataFrame
import pandas as pd df = pd.DataFrame({ 'Date': ['1993-01-29', '1993-02-01', '1993-02-02', '1993-02-03', '1993-02-04', '1993-02-05', '1993-02-08', '1993-02-09', '1993-02-10', '1993-02-11', '1993-02-12', '1993-02-16', '1993-02-17', '1993-02-18', '1993-02-23', '1993-02-24', '1993-02-25', '1993-02-26'], 'Ratio': [0.44, 0.44, 0.45, 0.44, 0.44, 0.56, 0.59, 0.58, 0.57, 0.54, 0.53, 0.47, 0.42, 0.38, 0.35, 0.39, 0.43, 0.46] })
需求规则
新增Signal列,默认值为True,需遵循以下逻辑:
- 监测
Ratio列的数值变化,当出现连续两次下降时,将这两次下降之后的所有Signal设为False - 处于
False状态时,直到出现连续两次上升,才从该节点之后恢复Signal为True - 规则需在整列循环执行
对应示例逻辑:
- 第6→7、7→8行出现连续两次下降,因此第9行开始
Signal变为False - 第14→15、15→16行出现连续两次上升,因此第17行
Signal恢复为True
预期输出
Signal 0 True 1 True 2 True 3 True 4 True 5 True 6 True 7 True 8 True 9 False 10 False 11 False 12 False 13 False 14 False 15 False 16 False 17 True
解决方案代码
# 计算Ratio的差分,标记每一步变化:上升(1)、下降(-1)、不变(0) df['diff'] = df['Ratio'].diff().apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0)) # 初始化Signal列为全True df['Signal'] = True # 状态标记:当前是否处于Signal=False的阶段 in_false_mode = False for i in range(2, len(df)): # 未关闭信号时,检测连续两次下降 if not in_false_mode and df['diff'].iloc[i-1] == -1 and df['diff'].iloc[i] == -1: df.loc[i+1:, 'Signal'] = False in_false_mode = True # 处于关闭状态时,检测连续两次上升 elif in_false_mode and df['diff'].iloc[i-1] == 1 and df['diff'].iloc[i] == 1: df.loc[i+1:, 'Signal'] = True in_false_mode = False # 删除临时差分列 df = df.drop('diff', axis=1) # 查看结果 print(df['Signal'])
代码说明
- 先通过差分计算
Ratio的每一步变化状态,简化后续连续变化的判断 - 用状态变量
in_false_mode追踪当前是否需要保持Signal=False - 遍历数据时,根据当前状态和连续变化的条件,批量修改后续行的
Signal值,避免逐行修改提升效率 - 最后清理临时生成的差分列,得到目标结果
内容的提问来源于stack exchange,提问作者MasayoMusic
相关产品推荐
相关产品推荐

