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

如何在Pandas中基于前序行与多列计算SMA值?

问题描述

我有一个结构如下的Pandas DataFrame,初始状态下SMA列与Index Value列数值完全一致。需要调整SMA列数值,使其遵循公式:

当前行SMA = 前一行SMA + 当前行ER ×(当前行Index Value - 前一行SMA)

尝试用shift方法实现:

df['SMA']=df['SMA'].shift(1) + df['ER'] * (df['Index Value'] - df['SMA'].shift(1))

但该方法无法满足首行SMA值与Index Value首值保持一致的要求,且因为shift调用的是原始SMA列的前一行值,无法实现递推计算,因此需要最优实现方案。

示例DataFrame代码:

data = {
    'Date': ['9/5/2023', '9/6/2023', '9/7/2023', '9/8/2023', '9/11/2023', '9/12/2023', 
             '9/13/2023', '9/14/2023', '9/15/2023', '9/18/2023', '9/19/2023', '9/20/2023', 
             '9/21/2023', '9/22/2023', '9/25/2023', '9/26/2023', '9/27/2023', '9/28/2023', 
             '9/29/2023'],
    'Index Value': [4496.83, 4465.48, 4451.14, 4457.49, 4487.46, 4461.9, 4467.44, 
                    4505.1, 4450.32, 4453.53, 4443.95, 4402.2, 4330, 4320.06, 
                    4337.44, 4273.53, 4274.51, 4299.7, 4288.05],
    'ER': [0.15066, 0.157105, 0.218561, 0.233893, 0.233709, 0.191352, 0.090935, 
           0.398004, 0.127833, 0.062296, 0.198933, 0.382776, 0.494406, 0.541878, 
           0.44323, 0.489456, 0.466276, 0.396806, 0.52569],
    'SMA': [4496.83, 4465.48, 4451.14, 4457.49, 4487.46, 4461.9, 4467.44, 4505.1, 
            4450.32, 4453.53, 4443.95, 4402.2, 4330, 4320.06, 4337.44, 4273.53, 
            4274.51, 4299.7, 4288.05]
}

df = pd.DataFrame(data)
解决方案

为什么shift方法无效

df['SMA'].shift(1)调用的是原始SMA列的前一行值,而非计算后更新的值,因此无法实现递推计算,且首行会生成NaN,不符合需求。


方案1:迭代计算(直观易懂,适合小数据集)

直接循环从第二行开始,使用上一行计算后的SMA值更新当前行:

# 保留首行SMA值不变
for i in range(1, len(df)):
    prev_sma = df.loc[i-1, 'SMA']
    current_er = df.loc[i, 'ER']
    current_index = df.loc[i, 'Index Value']
    df.loc[i, 'SMA'] = prev_sma + current_er * (current_index - prev_sma)

优点:逻辑简单,容易调试;缺点:数据集较大时效率较低。


方案2:使用expanding.apply(Pandas原生,无显式循环)

利用expanding窗口逐步累积计算,通过自定义函数实现递推逻辑:

def calculate_sma(window):
    # window是当前窗口的Series,包含到当前行的所有数据
    if len(window) == 1:
        return window['Index Value'].iloc[0]
    prev_sma = window['SMA'].iloc[-2]
    current_er = window['ER'].iloc[-1]
    current_index = window['Index Value'].iloc[-1]
    return prev_sma + current_er * (current_index - prev_sma)

# 重置SMA列为初始值(或者直接用Index Value列计算)
df['SMA'] = df['Index Value']
df['SMA'] = df.expanding().apply(calculate_sma, raw=False)

优点:符合Pandas风格,无显式循环;缺点:效率略低于迭代法,大数据集下表现一般。


方案3:Numba加速迭代(高效,适合大数据集)

用Numba的JIT编译加速迭代计算,大幅提升效率:
首先需要安装Numba:pip install numba

import numba
import numpy as np

@numba.jit(nopython=True)
def compute_sma_numba(index_values, er_values):
    n = len(index_values)
    sma = np.empty(n, dtype=np.float64)
    sma[0] = index_values[0]
    for i in range(1, n):
        sma[i] = sma[i-1] + er_values[i] * (index_values[i] - sma[i-1])
    return sma

# 调用函数计算并赋值
df['SMA'] = compute_sma_numba(df['Index Value'].values, df['ER'].values)

优点:效率极高,适合十万级以上的大数据集;缺点:需要额外安装Numba库,代码依赖第三方工具。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 15:23:13