You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Pandas当前列值为np.where设置条件?附示例DataFrame

用Pandas实现状态延续的TEST列逻辑

嘿,我太懂这种感觉了——Excel里靠拖拽公式就能搞定的状态延续逻辑,到Pandas里一开始确实容易卡壳。先把你的需求和示例数据理清楚:

示例数据与逻辑说明

你的DataFrame子集如下(注释是核心逻辑):

DATEIN200D_MATEST逻辑说明
10/30/2013010初始未触发状态
10/31/2013010未满足触发条件
11/1/2013111触发条件:IN与200D_MA均为1,TEST设为1
11/4/2013011延续条件:上一行TEST为1且200D_MA为1
11/5/2013011延续条件同上
11/6/2013011保持激活状态
11/7/2013011保持激活状态
11/8/2013011保持激活状态
11/11/2013000终止条件:200D_MA为0,TEST重置为0

简单来说,就是触发后保持激活状态,直到终止条件出现。

两种实现方案

方案1:循环实现(直观易懂,适合小数据集)

这种方式和Excel公式的逻辑最接近,逐行判断状态:

import pandas as pd

# 构造示例数据
data = {
    'DATE': ['10/30/2013', '10/31/2013', '11/1/2013', '11/4/2013', '11/5/2013', '11/6/2013', '11/7/2013', '11/8/2013', '11/11/2013'],
    'IN': [0, 0, 1, 0, 0, 0, 0, 0, 0],
    '200D_MA': [1, 1, 1, 1, 1, 1, 1, 1, 0],
    'TEST': [0, 0, 1, 1, 1, 1, 1, 1, 0]
}
df = pd.DataFrame(data)
df['DATE'] = pd.to_datetime(df['DATE'])

# 初始化激活状态
active = False
df['TEST_CALC'] = 0

# 逐行遍历更新状态
for idx, row in df.iterrows():
    # 触发条件:IN和200D_MA同时为1
    if row['IN'] == 1 and row['200D_MA'] == 1:
        active = True
    # 终止条件:200D_MA为0
    elif row['200D_MA'] == 0:
        active = False
    # 赋值当前状态
    df.loc[idx, 'TEST_CALC'] = 1 if active else 0

# 验证结果(TEST和TEST_CALC完全一致)
print(df[['DATE', 'IN', '200D_MA', 'TEST', 'TEST_CALC']])

方案2:矢量化实现(高效快速,适合大数据集)

如果你的DataFrame行数很多,循环会很慢,用Pandas的矢量化操作效率会高得多:

import pandas as pd

# 构造示例数据
data = {
    'DATE': ['10/30/2013', '10/31/2013', '11/1/2013', '11/4/2013', '11/5/2013', '11/6/2013', '11/7/2013', '11/8/2013', '11/11/2013'],
    'IN': [0, 0, 1, 0, 0, 0, 0, 0, 0],
    '200D_MA': [1, 1, 1, 1, 1, 1, 1, 1, 0],
    'TEST': [0, 0, 1, 1, 1, 1, 1, 1, 0]
}
df = pd.DataFrame(data)
df['DATE'] = pd.to_datetime(df['DATE'])

# 1. 标记触发事件(1)和终止事件(-1)
df['event'] = 0
df.loc[(df['IN'] == 1) & (df['200D_MA'] == 1), 'event'] = 1
df.loc[df['200D_MA'] == 0, 'event'] = -1

# 2. 累积求和,只要和>0就说明处于激活状态
df['TEST_CALC'] = (df['event'].cumsum() > 0).astype(int)

# 验证结果
print(df[['DATE', 'IN', '200D_MA', 'TEST', 'TEST_CALC']])

这个方法的核心是用cumsum()追踪事件的累积效果:触发事件让累积和+1,终止事件让累积和-1,只要累积和大于0,就说明还在激活状态。

注意事项

  • 如果数据中存在多个触发-终止周期,两种方案都能完美处理
  • 矢量化方案的效率是循环的几十甚至上百倍,大数据集优先选择这个

内容的提问来源于stack exchange,提问作者J Westwood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:14:11