Welles Wilder使用pandas计算移动平均值

3
我正在尝试在panda数据框中计算Welles Wilder类型的移动平均(也称为累积移动平均)。
计算'A'系列的Wilder移动平均值的方法如下: - 计算"A"中前'n'个值的平均值,并将其设置为第'n'个位置的平均值。 - 对于以下值,使用(n-1)加权的先前平均值和加权后的当前系列值,并将所有值除以'n'。
我的问题是:如何以向量化的方式实现这一点?
我尝试迭代数据框(不建议这样做,因为速度慢)。它能工作,值是正确的,但我会收到一个错误信息:
SettingWithCopyWarning: 正在尝试设置DataFrame片段的副本上的值
这可能不是最有效的方法。
我的代码如下:
import pandas as pd
import numpy as np

#Building Random sample:
datas = pd.date_range('2020-01-01','2020-01-31')
np.random.seed(693)
A = np.random.randint(40,60, size=(31,1))
df = pd.DataFrame(A,index = datas, columns = ['A'])

period = 12 # Main parameter
initial_mean = A[0:period].mean() # Equation for the first value.

size = len(df.index)
df['B'] = np.full(size, np.nan)
df.B[period-1] = initial_mean

for x in range(period, size):
    df.B[x] = ((df.A[x] + (period-1)*df.B[x-1]) / period) # Equation for the following values. 

print(df)

请注意,Pandas TA 项目已经实现了Wilder's Moving Average。 - Rodrigo Licks
1个回答

4

您可以使用Pandas的ewm()方法,在adjust=False时完全如您所述:

When adjust is False, weighted averages are calculated recursively as:

weighted_average[0] = arg[0];
weighted_average[i] = (1-alpha)*weighted_average[i-1] + alpha*arg[i]

如果你想对前期间的项目进行简单平均,可以先这样做,并将ewm()应用于结果。

可以使用以下公式计算出一个序列,该序列由前期间的平均值和其他完全重复的项目组成:

pd.Series(
    data=[df['A'].iloc[:period].mean()],
    index=[df['A'].index[period-1]],
).append(
    df['A'].iloc[period:]
)

为了计算Wilder移动平均值并将其存储在新列'C'中,您可以使用以下代码:

df['C'] = pd.Series(
    data=[df['A'].iloc[:period].mean()],
    index=[df['A'].index[period-1]],
).append(
    df['A'].iloc[period:]
).ewm(
    alpha=1.0 / period,
    adjust=False,
).mean()

在这一点上,您可以计算 df['B'] - df['C'] 并且您会看到差异几乎为零(浮点数存在一些舍入误差)。因此,这等同于使用循环进行计算。
你可能想考虑跳过前的直接平均值,并从一开始就开始应用ewm(),这将假定第一行是第一次计算中的先前平均值。结果会略有不同,但一旦经过了几个,那些初始值就很难影响结果。
那将是一种更简单的计算方式:
df['D'] = df['A'].ewm(
    alpha=1.0 / period,
    adjust=False,
).mean()

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