如何在Python中无循环实现股票64日滚动最高价计算?
如何用无循环方式计算Pandas中的64日滚动最高价?
这个问题太常见了——用循环处理滚动窗口统计在数据量大的时候确实慢到让人崩溃,Pandas其实内置了专门的滚动窗口函数,完美解决你的需求,而且速度快到离谱。
最优解决方案:使用Pandas的rolling方法
Pandas的rolling函数是专门为滚动窗口计算设计的,底层用向量化实现,完全匹配你要的「过去64行(含当前行)的最大值」逻辑,代码简洁到一行搞定:
import pandas as pd # 读取数据(不需要额外转成DataFrame,read_csv直接返回DataFrame) df = pd.read_csv('vod_price.csv', delimiter=',') # 计算64日滚动最高价,min_periods=1保证前64行也能正常计算 df['3m high'] = df['PX_LAST'].rolling(window=64, min_periods=1).max() # 查看结果 print(df.head(70))
代码细节解释:
window=64:指定滚动窗口包含当前行在内的过去64条数据,和你原循环的(x-64):(x+1)切片逻辑完全一致min_periods=1:当窗口内数据不足64条时(比如前63行),仍计算现有数据的最大值,这和你原循环中前65行的处理逻辑对齐.max():对每个滚动窗口直接计算最大值,全程无循环,向量化操作效率拉满
为什么你的原循环代码这么慢?
你原来的循环是逐行切片计算最大值,每一次循环都要执行一次切片和max运算,时间复杂度是O(n*64)(n是总数据行数)。如果你的股票数据有几万行,这种方法会耗时几十秒甚至更久。而rolling方法是底层用C实现的向量化操作,时间复杂度接近O(n),效率提升至少几百倍。
为什么你尝试的解决方案不对?
你写的这段代码逻辑完全偏离了滚动窗口的需求:
maxrange = df['PX_LAST'].between(df['PX_LAST'].shift(64),df['PX_LAST']) df['3m high'] = df['PX_LAST'].loc[maxrange].max()
df['PX_LAST'].shift(64)是把数据向下偏移64行,相当于取当前行往前64位的值,这不是滚动窗口的范围between是判断当前值是否在「往前64行的值」和「当前值」之间,这个逻辑和滚动最大值毫无关系- 最后取
loc[maxrange].max()是拿满足条件的所有值的全局最大值,自然得到的是整列的最大值,而非每个窗口的滚动值
效率对比(真实场景参考)
假设你的数据集有10000行:
- 原循环方法:大概需要10~20秒(甚至更久)
rolling方法:仅需0.01秒左右
差距真的非常夸张!
内容的提问来源于stack exchange,提问作者pythonlearner13




