2013-07-30 100 views
4

我想使用熊猫来计算EWMA,但结果并不是我所期望的。我认为第四元素应该是13.179,而熊猫则是13.121。我通过documentation中指定的公式将衰减因子(a)转换为质量中心。我误解任何东西吗?熊猫EWMA不按预期工作

In[222]: y 
Out[222]: 
0   NaN 
1   NaN 
2 13.192161 
3 13.109292 
4 12.623850 
5 12.150520 
Name: data, dtype: float64 

In[223]: pd.ewma(y, com = 1.0/a - 1) 
Out[223]: 
0   NaN 
1   NaN 
2 13.192161 
3 13.120667 
4 12.701206 
5 12.237839 
dtype: float64 

In[224]: a 
Out[224]: 0.8408964152537145 

In[225]: a * 13.192161 + (1 - a) * 13.109292 
Out[225]: 13.17897624503566 

回答

3

由于文档说

a = com/(1 + com) 

它遵循

com = a/(1.0-a) 

(0 < =一个< 1)。


而且,存在于在开始周期"to account for imbalance in relative weightings"计算出的值作了调整。 为了确认式

enter image description here

让我们关闭该调整:

z = pd.ewma(x, com=a/(1.0-a), adjust=False) 
print(z) 

然后打印

0   NaN 
1   NaN 
2 2.098920 
3 3.850710 
4 5.246548 
5 6.344995 

和这个结果可以通过计算来模拟

import pandas as pd 
import numpy as np 
import numpy.testing.utils as NTU 

nan = np.nan 
x = pd.Series([nan, nan, nan, 13.109292, 12.623850, 12.150520]) 
a = 0.8408964152537145 
z = pd.ewma(x, com=a/(1.0-a), adjust=False) 

def nanzero(x): 
    return 0 if np.isnan(x) else x 

x.ffill(inplace=True) 
y = [x[0]] 
for xt in x[1:]: 
    yt1 = y[-1] 
    if np.isnan(yt1) and np.isnan(xt): 
     yt = nan 
    else: 
     yt1 = nanzero(yt1) 
     xt = nanzero(xt) 
     yt = a*yt1 + (1-a)*xt 
     # yt = (1-a)*yt1 + a*xt 
    y.append(yt) 
y = pd.Series(y) 

NTU.assert_allclose(y,z) 
+0

它看起来像有一个错字。在我的链接提供的文档中,它表示a = 1 /(c + 1)。谢谢。 – ezbentley

+0

这是建议的文档修复(从一段时间回来).....如果这看起来是正确的,你可以评论一个人吗?感谢:https://github.com/pydata/pandas/pull/4321 – Jeff

+0

@Jeff:我还没有研究定义ewma的C代码,所以上面的代码可能不完全复制ewma,但它似乎表明至少在一些简单情况下,yt = a * yt1 +(1-a)* xt'是正确的公式。我已经在[在github页面上](https://github.com/pydata/pandas/pull/4321)留下了一条评论。 – unutbu