如何在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
相关产品推荐
相关产品推荐

