- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
如何在 NumPy 中获得指数加权移动平均线,就像 pandas 中的以下内容一样?
import pandas as pd
import pandas_datareader as pdr
from datetime import datetime
# Declare variables
ibm = pdr.get_data_yahoo(symbols='IBM', start=datetime(2000, 1, 1), end=datetime(2012, 1, 1)).reset_index(drop=True)['Adj Close']
windowSize = 20
# Get PANDAS exponential weighted moving average
ewm_pd = pd.DataFrame(ibm).ewm(span=windowSize, min_periods=windowSize).mean().as_matrix()
print(ewm_pd)
我用 NumPy 尝试了以下操作
import numpy as np
import pandas_datareader as pdr
from datetime import datetime
# From this post: http://stackoverflow.com/a/40085052/3293881 by @Divakar
def strided_app(a, L, S): # Window len = L, Stride len/stepsize = S
nrows = ((a.size - L) // S) + 1
n = a.strides[0]
return np.lib.stride_tricks.as_strided(a, shape=(nrows, L), strides=(S * n, n))
def numpyEWMA(price, windowSize):
weights = np.exp(np.linspace(-1., 0., windowSize))
weights /= weights.sum()
a2D = strided_app(price, windowSize, 1)
returnArray = np.empty((price.shape[0]))
returnArray.fill(np.nan)
for index in (range(a2D.shape[0])):
returnArray[index + windowSize-1] = np.convolve(weights, a2D[index])[windowSize - 1:-windowSize + 1]
return np.reshape(returnArray, (-1, 1))
# Declare variables
ibm = pdr.get_data_yahoo(symbols='IBM', start=datetime(2000, 1, 1), end=datetime(2012, 1, 1)).reset_index(drop=True)['Adj Close']
windowSize = 20
# Get NumPy exponential weighted moving average
ewma_np = numpyEWMA(ibm, windowSize)
print(ewma_np)
但是结果和pandas中的不一样。
是否有更好的方法可以直接在 NumPy 中计算指数加权移动平均值并获得与 pandas.ewm().mean()
完全相同的结果? ?
在 pandas 解决方案的 60,000 个请求中,我得到了大约 230 秒。我确信使用纯 NumPy 可以显着减少。
最佳答案
我想我终于破解了!
这是 numpy_ewma
函数的矢量化版本,据称它可以从 @RaduS's post
产生正确的结果-
def numpy_ewma_vectorized(data, window):
alpha = 2 /(window + 1.0)
alpha_rev = 1-alpha
scale = 1/alpha_rev
n = data.shape[0]
r = np.arange(n)
scale_arr = scale**r
offset = data[0]*alpha_rev**(r+1)
pw0 = alpha*alpha_rev**(n-1)
mult = data*pw0*scale_arr
cumsums = mult.cumsum()
out = offset + cumsums*scale_arr[::-1]
return out
进一步提升
我们可以通过一些代码重用来进一步提升它,就像这样 -
def numpy_ewma_vectorized_v2(data, window):
alpha = 2 /(window + 1.0)
alpha_rev = 1-alpha
n = data.shape[0]
pows = alpha_rev**(np.arange(n+1))
scale_arr = 1/pows[:-1]
offset = data[0]*pows[1:]
pw0 = alpha*alpha_rev**(n-1)
mult = data*pw0*scale_arr
cumsums = mult.cumsum()
out = offset + cumsums*scale_arr[::-1]
return out
运行时测试
让我们针对大数据集的同一个循环函数对这两个函数进行计时。
In [97]: data = np.random.randint(2,9,(5000))
...: window = 20
...:
In [98]: np.allclose(numpy_ewma(data, window), numpy_ewma_vectorized(data, window))
Out[98]: True
In [99]: np.allclose(numpy_ewma(data, window), numpy_ewma_vectorized_v2(data, window))
Out[99]: True
In [100]: %timeit numpy_ewma(data, window)
100 loops, best of 3: 6.03 ms per loop
In [101]: %timeit numpy_ewma_vectorized(data, window)
1000 loops, best of 3: 665 µs per loop
In [102]: %timeit numpy_ewma_vectorized_v2(data, window)
1000 loops, best of 3: 357 µs per loop
In [103]: 6030/357.0
Out[103]: 16.89075630252101
大约有 17 倍的加速!
关于python - NumPy 版本的 "Exponential weighted moving average",相当于 pandas.ewm().mean(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42869495/
C++ 中的标准“映射”容器允许您插入右值: T x; std::map m; // m[1]; // populate "1" auto it = m.insert(std::make_pair(
我们知道 std::move does not actually move anything .它只是将左值引用 (&) 转换为右值引用 (&&)。 那么在下面的例子中,拷贝构造函数是如何被调用的呢?
http://en.cppreference.com/w/cpp/language/rule_of_three 几个月前我开始使用 c++11并观看了五人规则。 所以..我开始将复制构造函数/复制赋值
这个问题在这里已经有了答案: In what scenarios should I expect to explicitly need to implement a move constructor
我有一个类似于下面的对象,我正在尝试为它实现一个 move 构造函数,这样你就可以为 std::vector 插入一个. struct Mesh { std::vector vPoint
这个问题在这里已经有了答案: How to create an std::function from a move-capturing lambda expression? (3 个回答) 关闭7年前
我有一个源文件,我正在使用它 move 到一个存档目录 关闭。 move (srcfile,dstdir) 但是当存档目标目录中已经存在相同的文件时,它会抛出一个错误,指出无法 move 文件已经存在
这应该有效,但无效并给出以下错误(如下)。 我读过几篇关于 stackoverflow 的帖子 here和 here但在这种情况下似乎没有一个好的答案。我真的希望我只是错过了一些愚蠢的东西,我已经在这
我似乎无法弄清楚为什么会这样。当我运行以下代码时: $uref = APACHE_ROOT . UPLOAD_PATH . $applicant . "_ref_{$email}_{$year}";
我似乎无法弄清楚为什么会这样。当我运行以下代码时: $uref = APACHE_ROOT . UPLOAD_PATH . $applicant . "_ref_{$email}_{$year}";
我的表格行可以上下 move ,但我的问题是数据表行取代了表格标题(第一行)。 我想要一个固定的第一行,这样当您单击向上箭头时,您就不会向上 move 该行来替换标题。 我尝试了一些条件逻辑来检查当前
正如我在Move constructor/operator=中询问的那样,过了一段时间,我同意并接受了这个问题的正确答案,我只是在想,是否有类似“移动析构函数” 这样的东西会在每次移动的对象上调用会有
如果我有一个像这样的 C 类: class C { std::string s; public: C(std::string& s) : s(s) {} C(std::str
我是 C++11 的新手,发现 move 语义和复制省略非常适合编写优雅高效的代码。不过我有一些问题想请教。这里我写了一个模板类 matrix.hpp 并用它来测试 move 语义的行为。 #incl
我在我们的项目中遇到了这样的代码: class A { public: A(A&& obj): valid_(false), data_(obj.data_) {} //... void
move 语义在这个例子中是如何工作的: struct test { int ii[10]; int i; }; test f() { test a; std::cou
假设我有一个类型为 A 的对象 a。 如果我想将其 move 到函数foo(A)。 一个选择是执行 foo(std::move(a)),这将调用 move 构造函数。 但是,假设我正在使用一个我无法控
我用 move 复制构造函数和 move 复制赋值运算符创建了一个简单的应用程序,并且在它们中的每一个上我都做了一个 cout 语句来告诉我,它们正在执行。但是在执行过程中,我没有看到 move 复制
相关问题: Why this move constructor is not called wtih rvalue temporary? [duplicate] Move Constructor vs
我正在努力研究 move 构造函数,并希望通过这个问题获得更多见解。这是一个简单的类。 class A { private: vector Bs; public: /* ..
我是一名优秀的程序员,十分优秀!