如何使用pandas计算加权移动平均线

时间:2012-03-08 16:42:30

标签: python pandas

使用pandas我可以计算

  • 使用pandas.stats.moments.rolling_mean
  • 的简单移动平均线SMA
  • 使用pandas.stats.moments.ewma
  • 的指数移动平均线EMA

但是如何使用pandas计算维基百科http://en.wikipedia.org/wiki/Exponential_smoothing中描述的加权移动平均值(WMA)?

是否有用于计算WMA的pandas功能?

4 个答案:

答案 0 :(得分:4)

不,没有那种确切算法的实现。在这里创建了一个关于它的GitHub问题:

https://github.com/pydata/pandas/issues/886

我很乐意接受拉取请求 - 实现应该是简单的Cython编码并且可以集成到pandas.stats.moments

答案 1 :(得分:1)

如果 data 是 Pandas DataFrame 或 Series,并且您想对行计算 WMA,则可以使用

wma = data[::-1].cumsum().sum() * 2 / data.shape[0] / (data.shape[0] + 1)

如果您想要窗口长度为 n 的滚动 WMA,请使用

data.rolling(n).apply(lambda x: x[::-1].cumsum().sum() * 2 / n / (n + 1))

作为n = x.shape[0]。请注意,此解决方案可能比 Sander van den Oord 的解决方案慢一点,但您不必担心权重。

答案 2 :(得分:1)

使用权重构建内核,并使用 numpy.convolve 将其应用于您的系列。

import pandas as pd
import numpy as np

def wma(arr, period):
    kernel = np.arange(period, 0, -1)
    kernel = np.concatenate([np.zeros(period - 1), kernel / kernel.sum()])
    return np.convolve(arr, kernel, 'same')

df = pd.DataFrame({'value':np.arange(11)})
df['wma'] = wma(df['value'], 4)

这里我根据这个页面解释 WMA:https://en.wikipedia.org/wiki/Moving_average

对于这种类型的 WMA,权重应该是 n 个值的线性范围,加起来等于 1.0。

请注意,我用零填充内核的前面。这是因为我们想要一个“单边”窗口函数,以便时间序列中的“未来”值不会影响移动平均线。

numpy.convolve 速度快,不像 apply()! 如果您反转内核,您也可以使用 numpy.correlate

答案 3 :(得分:0)

使用大熊猫,您可以结合使用.rolling().apply()来计算加权移动平均值。
这是一个具有3个权重和window = 3的示例:

data = {'colA':random.randint(1, 6, 10)}
df = pd.DataFrame(data)

weights = np.array([0.5, 0.25, 0.25])
sum_weights = np.sum(weights)

df['weighted_ma'] = (df['colA']
    .rolling(window=3, center=True)
    .apply(lambda x: np.sum(weights*x) / sum_weights, raw=False)
)

请注意,在.rolling()中,我使用了参数center = True。您应该检查这是否适用于您的用例,或者是否需要center = False。