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

如何在Pandas中获取含上下单元格的滚动窗口最小值?

在Pandas中识别连续三单元格的局部最小值(含当前、上、下单元格)

我需要在Pandas中实现逻辑:对每一行的Close值,判断它是否是当前行、上一行、下一行这三个连续单元格中的最小值。尝试过scipy的arglextrema,但它无法实现这种滚动窗口的计算逻辑。

尝试过以下自定义函数,但效果不符合预期:

def pivot_swing_low(df):
    data = df.copy()
    data['d1'] = data.Close.shift(-1)
    data['d3'] = data.Close.shift(0)
    data['d4'] = data.Close.shift(1)
    data['minPL'] = data[['d1', 'd3', 'd4']].min(axis=1)
    data['PL'] = np.where(data['minPL'] == data['d3'], data['d3'], "NaN")
    
    data['recentPL'] = data.PL.shift(2).astype(float).fillna(method='ffill')

    data = data.drop(columns=['d1', 'd3', 'd4'])
    return data

这个函数仅能捕获到第33行的最小值,但实际上第31行也应该被识别为局部最小值。

相关数据示例(仅展示关键行):

38.78   1671068699999   2022-12-15 01:44:59.999     NaN     NaN     -0.37   0.00    0.37    0.023571    0.054286    0.023125    0.057698    0.400805    28.612474   NaN     NaN     38.78   38.78   39.15
30  38.79   1671068999999   2022-12-15 01:49:59.999     NaN     NaN     0.01    0.01    0.00    0.022857    0.054286    0.022188    0.053576    0.414137    29.285496   NaN     NaN     38.48   NaN     39.15
31  38.48   1671069299999   2022-12-15 01:54:59.999     NaN     NaN     -0.31   0.00    0.31    0.021429    0.076429    0.020603    0.071892    0.286583    22.274722   22.274722   NaN     38.48   38.48   38.78
32  38.67   1671069599999   2022-12-15 01:59:59.999     NaN     NaN     0.19    0.19    0.00    0.035000    0.074286    0.032703    0.066757    0.489878    32.880419   NaN     NaN     38.37   NaN     38.78
33  38.37   1671069899999   2022-12-15 02:04:59.999     38.37000000     NaN     -0.30   0.00    0.30    0.035000    0.093571    0.030367    0.083417    0.364036    26.688174   NaN     NaN     38.37   38.37   38.48
34  38.58   1671070199999   2022-12-15 02:09:59.999     NaN     NaN     0.21    0.21    0.00    0.050000    0.090000    0.043198    0.077459    0.557687    35.802263   NaN     NaN     38.37   NaN     38.48
35  38.70   1671070499999   2022-12-15 02:14:59.999     NaN     NaN     0.12    0.12    0.00    0.058571    0.090000    0.048684    0.071926    0.676857    40.364625   NaN     40.364625   38.58   NaN     38.37

问题原因分析

原函数的核心逻辑没问题,但存在一个关键错误:将非最小值的情况赋值为字符串"NaN",而非NumPy的np.nan。后续执行astype(float)时,字符串"NaN"会被转为np.nan,但同时可能导致原本有效的值被错误转换,最终造成第31行的最小值未被正确保留。

修正后的解决方案

使用Pandas的滚动窗口rolling方法,更简洁且准确地实现需求:

import pandas as pd
import numpy as np

def pivot_swing_low(df):
    data = df.copy()
    # 以当前行为中心,取上、中、下三行的最小值
    data['window_min'] = data['Close'].rolling(window=3, center=True).min()
    # 判断当前Close是否为窗口最小值,是则保留值,否则为np.nan
    data['PL'] = np.where(data['Close'] == data['window_min'], data['Close'], np.nan)
    # 处理recentPL字段,保持原逻辑
    data['recentPL'] = data['PL'].shift(2).fillna(method='ffill')
    # 可选择删除中间字段window_min
    # data = data.drop(columns=['window_min'])
    return data

说明

  • rolling(window=3, center=True):指定窗口大小为3,且以当前行为中心,正好覆盖上一行、当前行、下一行三个连续单元格。
  • 替换字符串"NaN"为np.nan,保证数据类型统一,避免转换错误。
  • 修正后,第31行的Close=38.48会被正确识别为窗口最小值(对应窗口值:38.79、38.48、38.67),第33行的38.37也会被正常捕获。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 07:55:28