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

如何用Pandas高效实现纳尔逊第3法则(Nelson's Rule 3)

用Pandas高效实现纳尔逊第3法则(标记所有符合条件的数据点)

纳尔逊第3法则要求识别连续6个持续递增或递减的数据点,你的初始方法只能标记序列的最后一个点,核心问题是滚动窗口仅向后验证,未覆盖序列中的前置点。以下是基于Pandas向量化操作的高效解决方案,无需低效的逐行遍历:

实现思路

  1. 通过diff()生成数据点间的增减布尔序列;
  2. 用滚动窗口找到所有满足「连续5个递增/递减差值」的位置(对应原数据6个连续点);
  3. 将每个符合条件的窗口对应的所有原数据点标记为True,通过范围赋值实现批量标记。

完整代码

import pandas as pd

# 示例数据
data = pd.DataFrame({"values": [1,2,3,4,5,6,7,5,6,5,3]})

def mark_nelson_rule3(df, col='values'):
    # 1. 生成递增/递减布尔序列(diff后第一个值为NaN,不影响后续滚动计算)
    incr = df[col].diff() > 0
    decr = df[col].diff() < 0

    # 2. 标记所有符合连续6个递增的点
    incr_mark = pd.Series(False, index=df.index)
    # 滚动窗口大小为5:对应原数据6个连续递增点(需要5个连续的递增差值)
    incr_windows = incr.rolling(5, min_periods=5).sum() == 5
    # 为每个符合条件的窗口,批量标记对应的原数据点
    for idx in incr_windows[incr_windows].index:
        incr_mark.loc[idx-5 : idx] = True

    # 3. 标记所有符合连续6个递减的点
    decr_mark = pd.Series(False, index=df.index)
    decr_windows = decr.rolling(5, min_periods=5).sum() == 5
    for idx in decr_windows[decr_windows].index:
        decr_mark.loc[idx-5 : idx] = True

    # 4. 合并递增/递减的标记结果
    return incr_mark | decr_mark

# 应用函数并输出结果
nelson_rule3 = mark_nelson_rule3(data)
print(nelson_rule3)

输出结果

0     True
1     True
2     True
3     True
4     True
5     True
6     True
7    False
8    False
9    False
10   False
dtype: bool

关键说明

  • 滚动窗口大小设为5:因为原数据连续6个递增点,对应diff()后会产生5个连续的True值;
  • 范围赋值loc[idx-5 : idx]:将每个符合条件的窗口对应的原数据点全部标记,避免仅标记最后一个点;
  • 整体效率:仅在最后遍历符合条件的窗口位置(通常数量极少),核心逻辑依赖Pandas向量化操作,远快于iterrows()或自定义apply()。

内容的提问来源于stack exchange,提问作者Oliver Cohen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:01:22