Pandas - 指数加权移动平均值 - 类似于Excel

4
考虑我有一个包含两列A和B的10行数据帧,如下所示:
    A  B
0  21  6
1  87  0
2  87  0
3  25  0
4  25  0
5  14  0
6  79  0
7  70  0
8  54  0
9  35  0

在Excel中,我可以像这样计算滚动均值,但要排除第一行:enter image description here enter image description here。那么如何在pandas中实现呢?下面是我尝试过的方法:
import pandas as pd

df = pd.read_clipboard() #copying the dataframe given above and calling read_clipboard will get the df populated
for i in range(1, len(df)):
    df.loc[i, 'B'] = df[['A', 'B']].loc[i-1].mean()

这个方法可以得到与Excel匹配的期望结果。但是,有没有更好的使用pandas的方法呢?我尝试使用expandingrolling,但没有得到期望的结果。

我对你在这里的目标有些困惑。例如,系列A的“标准”移动平均值,窗口长度为2,公式应该是=B2中的=AVERAGE(A2:A1),而不是=AVERAGE(A1,B1)。鉴于您已经接受了一个答案,我假设您已经得到了您想要的东西,但如果您有时间提供一些细节,那将是很酷的事情。 - vestland
1
我正在尝试创建平均线蜡烛图。当前柱的开盘价是前一根蜡烛的开盘价和收盘价的平均值。更多细节请参考此链接https://www.quantiacs.com/Blog/Intro-to-Algorithmic-Trading-with-Heikin-Ashi.aspx。 - Abbas
1个回答

5
你使用的是指数加权移动平均,而不是简单移动平均。这就是为什么pd.DataFrame.rolling无法工作的原因。你可能需要考虑使用pd.DataFrame.ewm

从这里开始:

df

Out[399]: 
    A  B
0  21  6
1  87  0
2  87  0
3  25  0
4  25  0
5  14  0
6  79  0
7  70  0
8  54  0
9  35  0

df['B'] = df["A"].shift().fillna(df["B"]).ewm(com=1, adjust=False).mean()
df

Out[401]: 
    A          B
0  21   6.000000
1  87  13.500000
2  87  50.250000
3  25  68.625000
4  25  46.812500
5  14  35.906250
6  79  24.953125
7  70  51.976562
8  54  60.988281
9  35  57.494141

即使只有10行,用这种方式编写可以通过%timeit将代码的速度提高约10倍(从10.3ms减少到959微秒)。在100行时,这个系数变成了100 (1.1ms对比110ms)。

3
我认为你可以使用adjust=False,例如:df["A"].shift().fillna(df["B"]).ewm(com=1, adjust=False).mean() - DSM
@DSM 绝对正确。我的眼睛一直跳过那行。已更新。 - EFT

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