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

如何用Pandas标记滚动窗口内首次出现的新高点?

问题描述

我用以下代码标记收盘价是否突破52周新高:

df1['52wkh'] = df1['high'].rolling(min_periods=1, window=252).max()
df1['is_52wkch'] = df1['close'] >= df1.shift(1)['52wkh']

运行后得到的数据如下:

close         high        52wkh  is_52wkch
date                                                        
2021-11-22  4682.939941  4743.830078  4743.830078      False
2021-12-27  4791.189941  4791.490234  4791.490234       True
2021-12-28  4786.350098  4807.020020  4807.020020      False
2021-12-30  4778.729980  4808.930176  4808.930176      False
2022-01-04  4793.540039  4818.620117  4818.620117      False
2023-06-12  4338.930176  4340.129883  4340.129883       True
2023-06-13  4369.009766  4375.370117  4375.370117       True
2023-06-14  4372.589844  4391.819824  4391.819824      False
2023-06-15  4425.839844  4439.200195  4439.200195       True
2023-06-16  4409.589844  4448.470215  4448.470215      False

但我需要仅标记滚动窗口内首次出现的新高点,期望结果如下:

close         high        52wkh  is_52wkch
date                                                        
2021-11-22  4682.939941  4743.830078  4743.830078      False
2021-12-27  4791.189941  4791.490234  4791.490234       True
2021-12-28  4786.350098  4807.020020  4807.020020      False
2021-12-30  4778.729980  4808.930176  4808.930176      False
2022-01-04  4793.540039  4818.620117  4818.620117      False
2023-06-12  4338.930176  4340.129883  4340.129883       True
2023-06-13  4369.009766  4375.370117  4375.370117      False
2023-06-14  4372.589844  4391.819824  4391.819824      False
2023-06-15  4425.839844  4439.200195  4439.200195      False
2023-06-16  4409.589844  4448.470215  4448.470215      False

我尝试过分组计数但没成功,因为需要在滚动52周窗口内统计True值的数量。目前想到的解决方案是:

df1['52wkh'] = df1['high'].rolling(min_periods=1, window=252).max()
# 标记所有符合条件的52周新高
df1['is_52wkch'] = df1['close'] >= df1.shift(1)['52wkh']
# 统计过去52周内上述标记的出现次数
df1['is_52wkch_cnt'] = df1.rolling(window=252)['is_52wkch'].sum()

之后通过筛选is_52wkch==True且is_52wkch_cnt == 1来标记滚动窗口内的首次52周新高,请问这个思路是否正确?

解答

你的思路存在逻辑漏洞,无法准确实现需求:

  • 滚动窗口的sum()是统计窗口内所有True的总数,但后续出现新的新高点时,窗口内的True数量会累计增加,无法区分“首次”是针对当前这个新高值的首次突破,还是窗口内所有新高的第一次出现。

正确的实现逻辑应该聚焦于「52周新高值的首次更新」:

  1. 先识别52周新高值发生更新的日期:当当前的52wkh大于前一天的52wkh时,说明出现了新的52周高点。
  2. 再结合收盘价突破前一天新高的条件,仅在新高值首次出现且收盘价突破的日期标记为True。

具体代码如下:

# 计算52周滚动高点
df1['52wkh'] = df1['high'].rolling(min_periods=1, window=252).max()

# 标记52周新高值是否更新(当天出现了新的历史高点)
df1['new_52wkh'] = df1['52wkh'] > df1['52wkh'].shift(1)

# 仅当新高值更新,且收盘价突破前一天的52周高点时,标记为True
df1['is_52wkch'] = df1['new_52wkh'] & (df1['close'] >= df1['52wkh'].shift(1))

# 可选:删除中间辅助列
df1 = df1.drop('new_52wkh', axis=1)

运行后即可得到你期望的结果:只有当某个新的52周高点首次出现,且收盘价突破了之前的高点时,才会标记为True,后续再出现更高的高点但未满足首次突破条件时不会重复标记。

你原始代码中df1['close'] >= df1.shift(1)['52wkh']的逻辑是正确的,结合新高值更新的判断就能精准定位首次突破点。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 10:07:12