Pandas中EMA自引用计算及RSI模块调用报错的解决方法
解决EMA递归计算与pandas.stats弃用的问题
看起来你遇到了两个核心问题:一是EMA计算时引用未初始化的列导致的错误,二是pandas版本更新后pd.stats模块被移除引发的AttributeError。下面一步步帮你解决:
1. 修正EMA的递归计算逻辑
你的EMA公式写错了,而且尝试引用还未创建的EMA12/EMA26列,这肯定会报错。正确的EMA计算逻辑是:
- 初始值:用前N期收盘价的**简单移动平均(SMA)**作为第一期EMA
- 后续值:
EMA_t = (当前收盘价 × 权重系数) + (前一期EMA × (1 - 权重系数)),其中权重系数multiplier = 2/(周期+1)
用pandas的ewm方法可以高效实现这个逻辑,不需要手动循环:
import pandas as pd import numpy as np # 读取数据并清理列 df = pd.read_csv(r"C:\Users\drnov\Desktop\Stocks\TNA (3).csv") # 保留Close列,删除其他列 df = df[['Close']] # 保留两位小数 df['Close'] = round(df['Close'] * 100) / 100 # 计算EMA12和EMA26 period12 = 12 period26 = 26 # 用adjust=False匹配递归式EMA计算(和你原公式逻辑一致) df['EMA12'] = df['Close'].ewm(span=period12, adjust=False).mean() df['EMA26'] = df['Close'].ewm(span=period26, adjust=False).mean() # 保留两位小数 df['EMA12'] = round(df['EMA12'] * 100) / 100 df['EMA26'] = round(df['EMA26'] * 100) / 100 # 计算MACD df['MACD'] = df['EMA12'] - df['EMA26'] df['MACD'] = round(df['MACD'] * 100) / 100
2. 修正RSI计算(替代弃用的pd.stats)
pd.stats.moments.ewma在pandas 0.20+版本就被移除了,现在用Series.ewm()来计算指数加权平均。下面是修正后的RSI函数:
def RSI(series, period=14): # 计算价格变动 delta = series.diff() # 分离上涨和下跌幅度 u = delta.where(delta > 0, 0) d = -delta.where(delta < 0, 0) # 用ewm计算加权平均(替代旧的pd.stats.moments.ewma) u_ewm = u.ewm(com=period-1, adjust=False).mean() d_ewm = d.ewm(com=period-1, adjust=False).mean() # 计算RS和RSI rs = u_ewm / d_ewm rsi = 100 - 100 / (1 + rs) return rsi # 计算RSI并添加到DataFrame df['RSI'] = RSI(df['Close'], 14) df['RSI'] = round(df['RSI'] * 100) / 100
3. 结果验证说明
整合代码运行后,就能得到你期望的计算结果。需要注意:
ewm(span=period, adjust=False)完全匹配手动递归的EMA计算逻辑,避免了引用未初始化列的问题- 初始的RSI值会在第14行之后才出现(需要14期数据计算),前面的行会显示
NaN,你可以用df.dropna()或者填充初始值来处理
内容的提问来源于stack exchange,提问作者Brandon Nova
相关产品推荐
相关产品推荐

