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

如何在Python中实现无循环的14日条件平滑移动平均列?

无循环实现仅包含delta正值的14日平滑移动平均

嘿,我懂你这种困扰——用Python循环处理股票数据,一旦数据集大起来速度简直没法忍。你之前尝试用ewm但结果不对,其实是没抓准你要的平滑公式和ewm参数的对应关系,咱们来搞定它。

先拆解你的需求公式

你要计算的avg_gain本质是个带条件的指数加权移动平均,核心公式是:

Avg_Gain(t) = (Avg_Gain(t-1) * 13 + max(delta(t), 0)) / 14

换个写法就是:

Avg_Gain(t) = (1/14)*max(delta(t),0) + (13/14)*Avg_Gain(t-1)

这完全符合递推式EWMA的结构,只是需要先把delta的负值替换为0,再用特定的权重计算。

为什么之前的ewm尝试不对?

默认的ewm(span=14).mean()用的是alpha=2/(span+1)(也就是2/15≈0.133),和你需要的alpha=1/14≈0.071不匹配。而且默认的adjust=True会计算累积加权平均,不是你要的递推式逐步更新,所以结果自然对不上。

正确的无循环实现方案

直接用Pandas的向量化操作,效率拉满:

import numpy as np
import pandas as pd

# 读取数据
df = pd.read_csv('stock_price.csv', delimiter=',')

# 计算每日涨跌幅delta
df['delta'] = df['PX_LAST'].pct_change()

# 生成gain列:仅保留delta的正值,负值替换为0(用clip比apply高效)
df['gain'] = df['delta'].clip(lower=0)

# 计算符合需求的平滑平均
# alpha=1/14对应公式里的权重,adjust=False强制递推式计算
df['avg_gain'] = df['gain'].ewm(alpha=1/14, adjust=False, min_periods=1).mean()

# 和原循环逻辑对齐,设置第一个值为0
df.loc[df.index[0], 'avg_gain'] = 0

# 查看结果
print(df[['Dates', 'PX_LAST', 'delta', 'avg_gain']])

关键参数解释

  • clip(lower=0):这是Pandas内置的向量化方法,比lambda x: x if x>0 else 0快得多,专门用来把数值限制在指定范围内。
  • alpha=1/14:对应你公式里的新值权重,1/14的新gain加上13/14的历史平均值,完美匹配你的循环逻辑。
  • adjust=False:这个参数一定要加!它会强制EWMA用递推的方式计算,和你手动循环的每一步完全一致,而不是用累积加权的方式。

效率对比

这个方法完全是底层优化过的向量化操作,时间复杂度是O(n),但执行速度比Python循环快几十甚至上百倍——尤其是当你的股票数据有几万条的时候,差别会特别明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:57:11