使用熊猫我可以计算
- 简单移动平均 SMA 使用
pandas.stats.moments.rolling_mean
- 指数移动平均 EMA 使用
pandas.stats.moments.ewma
但是我如何计算加权移动平均线 (WMA),如维基百科http://en.wikipedia.org/wiki/Exponential_smoothing中所述......使用熊猫?
是否有用于计算 WMA 的 pandas 函数?
使用熊猫我可以计算
pandas.stats.moments.rolling_mean
pandas.stats.moments.ewma
但是我如何计算加权移动平均线 (WMA),如维基百科http://en.wikipedia.org/wiki/Exponential_smoothing中所述......使用熊猫?
是否有用于计算 WMA 的 pandas 函数?
使用 pandas,您可以使用以下方法计算加权移动平均值 (wma):
.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
.
不,没有该确切算法的实现。在这里创建了一个关于它的 GitHub 问题:
https://github.com/pydata/pandas/issues/886
我很乐意为此提出拉取请求——实现应该是简单的 Cython 编码,并且可以集成到pandas.stats.moments
如果data
是 Pandas DataFrame 或 Series,并且您想在行上计算 WMA,您可以使用
wma = data[::-1].cumsum().sum() * 2 / data.shape[0] / (data.shape[0] + 1)
如果您想要窗口长度的滚动 WMA n
,请使用
data.rolling(n).apply(lambda x: x[::-1].cumsum().sum() * 2 / n / (n + 1))
作为n = x.shape[0]
. 请注意,此解决方案可能比 Sander van den Oord 的解决方案慢一些,但您不必担心权重。
使用权重构造一个内核,并使用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
如果您反转内核,您也可以使用。