有没有办法让 Pandas ewm 在固定的 windows 上运行?
Is there a way to get Pandas ewm to function on fixed windows?
我正在尝试使用 Pandas ewm function 来计算指数加权移动平均线。但是我注意到信息似乎贯穿于您的整个时间序列。这意味着每个数据点的 MA 都取决于不同数量的先前数据点。因此每个数据点的 ewm 函数在数学上都是不同的。
我想这里有些人有类似的问题
Does Pandas calculate ewm wrong?
但我确实尝试了他们的方法,但我没有得到我想要的功能。
def EMA(arr, window):
sma = arr.rolling(window=window, min_periods=window).mean()[:window]
rest = arr[window:]
return pd.concat([sma, rest]).ewm(com=window, adjust=False).mean()
a = pd.DataFrame([x for x in range(100)])
print(list(EMA(a, 10)[0])[-1])
print(list(EMA(a[50:], 10)[0])[-1])
在这个例子中,我有一个 1 到 100 的数组。我计算这个数组和 50-100 的数组的移动平均线。最后一个移动平均线应该是相同的,因为我只使用了 10 的 window。但是当我 运行 这段代码时,我得到两个不同的值,表明 ewm 确实依赖于整个系列。
IIUC,您在滚动 window 中要求 ewm,这意味着每 10 行 return 一个数字。如果是这样的话,那么我们可以使用步幅技巧:
编辑:更新功能仅适用于系列
def EMA(arr, window=10, alpha=0.5):
ret = pd.Series(index=arr.index, name=arr.name)
arr=np.array(arr)
l = len(arr)
stride = arr.strides[0]
ret.iloc[window-1:] = (pd.DataFrame(np.lib.stride_tricks.as_strided(arr,
(l-window+1,window),
(stride,stride)))
.T.ewm(alpha)
.mean()
.iloc[-1]
.values
)
return ret
测试:
a = pd.Series([x for x in range(100)])
EMA(a).tail(2)
# 98 97.500169
# 99 98.500169
# Name: 9, dtype: float64
EMA(a[:50]).tail(2)
# 98 97.500169
# 99 98.500169
# Name: 9, dtype: float64
EMA(a, 2).tail(2)
98 97.75
99 98.75
dtype: float64
随机数据测试:
a = pd.Series(np.random.uniform(0,1,10000))
fig, ax = plt.subplots(figsize=(12,6))
a.plot(ax=ax)
EMA(a,alpha=0.99, window=2).plot(ax=ax)
EMA(a,alpha=0.99, window=1500).plot(ax=ax)
plt.show()
输出:我们可以看到较大的 window(绿色)比较小的 window(橙色)波动性更小。
我正在尝试使用 Pandas ewm function 来计算指数加权移动平均线。但是我注意到信息似乎贯穿于您的整个时间序列。这意味着每个数据点的 MA 都取决于不同数量的先前数据点。因此每个数据点的 ewm 函数在数学上都是不同的。
我想这里有些人有类似的问题
Does Pandas calculate ewm wrong?
但我确实尝试了他们的方法,但我没有得到我想要的功能。
def EMA(arr, window):
sma = arr.rolling(window=window, min_periods=window).mean()[:window]
rest = arr[window:]
return pd.concat([sma, rest]).ewm(com=window, adjust=False).mean()
a = pd.DataFrame([x for x in range(100)])
print(list(EMA(a, 10)[0])[-1])
print(list(EMA(a[50:], 10)[0])[-1])
在这个例子中,我有一个 1 到 100 的数组。我计算这个数组和 50-100 的数组的移动平均线。最后一个移动平均线应该是相同的,因为我只使用了 10 的 window。但是当我 运行 这段代码时,我得到两个不同的值,表明 ewm 确实依赖于整个系列。
IIUC,您在滚动 window 中要求 ewm,这意味着每 10 行 return 一个数字。如果是这样的话,那么我们可以使用步幅技巧:
编辑:更新功能仅适用于系列
def EMA(arr, window=10, alpha=0.5):
ret = pd.Series(index=arr.index, name=arr.name)
arr=np.array(arr)
l = len(arr)
stride = arr.strides[0]
ret.iloc[window-1:] = (pd.DataFrame(np.lib.stride_tricks.as_strided(arr,
(l-window+1,window),
(stride,stride)))
.T.ewm(alpha)
.mean()
.iloc[-1]
.values
)
return ret
测试:
a = pd.Series([x for x in range(100)])
EMA(a).tail(2)
# 98 97.500169
# 99 98.500169
# Name: 9, dtype: float64
EMA(a[:50]).tail(2)
# 98 97.500169
# 99 98.500169
# Name: 9, dtype: float64
EMA(a, 2).tail(2)
98 97.75
99 98.75
dtype: float64
随机数据测试:
a = pd.Series(np.random.uniform(0,1,10000))
fig, ax = plt.subplots(figsize=(12,6))
a.plot(ax=ax)
EMA(a,alpha=0.99, window=2).plot(ax=ax)
EMA(a,alpha=0.99, window=1500).plot(ax=ax)
plt.show()
输出:我们可以看到较大的 window(绿色)比较小的 window(橙色)波动性更小。