Pandas的EWMA不如预期工作

4

我正在尝试使用pandas计算EWMA,但结果与我的预期不符。我认为第四个元素应该是13.179,但pandas给出的是13.121。我按照文档中指定的公式将衰减因子(a)转换为质心。我是否有什么误解?

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
1个回答

1

由于文档中提到

a = com/(1 + com)

它的意思是“因此”。
com = a/(1.0-a)

(对于 0 ≤ a < 1)。
此外,在开始期间,对计算值进行了调整,以解决相对权重不平衡的问题 "(链接1)"。为确认该公式。

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)

看起来有一个拼写错误。在我提供的链接中的文档中,它说 a = 1 / (c + 1)。谢谢。 - user1642513
这是之前提出的文档修复建议......你们其中有人能否评论一下这是否正确?谢谢:https://github.com/pydata/pandas/pull/4321 - Jeff
1
@Jeff:我还没有研究过定义ewma的C代码,所以上面的代码可能并不能完美地复制ewma,但它似乎表明对于至少一些简单情况,yt = a*yt1 + (1-a)*xt是正确的公式。我已经在github页面上留下了评论。 - unutbu
@Jeff:是的,我认为它们是。 - unutbu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接