python - 在 Python 中,通过重用以前的计算来计算 EMA 的更快方法是什么?
问题描述
我一直在使用 TA-Lib 来计算 EMA,但每次我向数组添加一个新数字时,TA-Lib 都会再次从头开始计算。
我正在对一组相当大的数据(> 1M 行)进行分析,这很慢。
添加新值时,计算新 EMA 的最快方法是什么?
解决方案
设x
为包含样本的长度向量n
,即x[0]
, ..., x[n-1]
。设y
为包含 EMA 的向量。然后y
由等式给出:
y[k] = y[k-1] * a + x[k] * (1-a)
EMA参数在哪里a
,介于0和1之间。越接近1,曲线越平滑。
因此,要计算 EMA,您只需要:
a = 0.9
y[0] = x[0]
for k in range(1, n):
y[k] = y[k-1]*a + x[k]*(1-a)
然后,如果您获得另一个样本,即x[n]
,您可以计算 EMAy[n]
而无需使用以下方法进行完整计算:
y[n] = y[n-1]*a + x[n]*(1-a)
这是伪代码,所以如果你使用列表,它应该是这样的:
y.append(y[-1]*a + x[-1]*(1-a))
编辑:
如果您真的想提高计算 EMA(一次整个 EMA)的速度,您可以使用numba和 numpy:
import numpy as np
from numba import njit
from timeit import timeit
n=1000000
x_np = np.random.randn(n) # your data
x_list = list(x_np)
a = 0.9
def ema_list(x, a):
y = [x[0]]
for k in range(1, n):
y.append(y[-1]*a + x[k]*(1-a))
return y
@njit("float64[:](float64[:], float64)")
def ema_np(x, a):
y = np.empty_like(x)
y[0] = x[0]
for k in range(1, n):
y[k] = y[k-1]*a + x[k]*(1-a)
return y
print(timeit(lambda: ema_list(x_list, a), number=1)) # 0.7080 seconds
print(timeit(lambda: ema_np(x_np, a), number=1)) # 0.008015 seconds
列表实现大约需要 708 毫秒,而 numba 和 numpy 需要 8 毫秒,大约快 88 倍。没有 numba 的 numpy 实现与列表实现所需的时间相似。
推荐阅读
- node.js - 为什么会发生这种情况,res.redirect() 方法的范围仅限于 express 中的 findByIdAndRemove 方法
- spring-boot - Spring boot千分尺datadog套接字连接错误
- node.js - 使用 res.redirect() 时,带有 Express 的 Node.js 不会重定向到外部 URL
- selenium - selenium 错误 WebDriverException:未知错误:asp 核心中没有 chrome 二进制文件
- r - 与其他方法相比,使用 Caret 包的 KNN 给出了不好的结果
- javascript - .bind this 在类方法中
- java - Java JFrame 意外地奇怪地删除组件
- r - 在 Google Colab 中,您如何在 Google Drive 中找到文件的路径。我正在使用 R
- java - 使用 Ridesharing 应用程序请求 RDMS Firebase 分片的高级建议
- javascript - 在Javascript中生成由函数映射返回的两个或多个项目