import numpy as np
import pandas as pd
df = pd.DataFrame({'data': [1, 2, 3, 4, 5]})
ewm1 = df['data'].ewm(span=2, adjust=False).mean()
ewm2 = df['data'].ewm(span=2, adjust=True).mean()
print(ewm1)
print(ewm2)
ewm1
[0] 1.000000
[1] 1.666667 = 1*(1/3) + 2*(2/3)
[2] 2.555556 = 1*(1/3)2 + 2(2/3)(1/3) + 3(2/3)
[3] 3.518519 = 1(1/3)3 + 2(2/3)(1/3)*2 + 3(2/3)(1/3) + 4(2/3)
[4] 4.506173 = 1*(1/3)*4 + 2(2/3)(1/3)*3 + 3(2/3)(1/3)*2 + 4(2/3)(1/3) + 5(2/3)
ewm2
0 1.000000
1 1.750000
2 2.615385
3 3.550000
4 4.520661
s = pd.Series([1, 3, 6, 10])
计算它的扩张窗口的指数平均值
要计算一个pandas
Series的扩张窗口(即每个窗口的结束点都是序列的最后一个元素)的指数移动平均值(EMA),你可以使用pandas
内置的ewm
方法。但是,请注意,ewm
通常用于计算固定窗口大小的指数移动平均值,而不是扩张窗口。在扩张窗口的情况下,每个元素的权重会随着窗口大小的变化而变化。
然而,如果我们假设你想计算的是一系列扩张窗口的EMA,其中每个窗口的结束点都是序列的最后一个元素,并且你想要的是每个窗口结束时的EMA值,那么你可以通过迭代序列并逐渐增加窗口大小来实现这一点。
以下是一个示例代码,展示了如何计算扩张窗口的EMA:
import pandas as pd
import numpy as np
# 定义Series
s = pd.Series([1, 3, 6, 10])
# 初始化一个列表来存储每个扩张窗口的EMA值
ema_values = []
# 迭代计算每个扩张窗口的EMA
for window_size in range(1, len(s) + 1):
# 使用ewm方法计算当前窗口大小的EMA
ema = s[:window_size].ewm(alpha=1 / window_size, adjust=False).mean().iloc[-1]
ema_values.append(ema)
# 将结果转换为Series
ema_series = pd.Series(ema_values, index=range(1, len(s) + 1))
print(ema_series)
在这个例子中,alpha
参数被设置为1 / window_size
,这意味着较新的观察值在EMA计算中的权重会随着窗口大小的增加而逐渐减小。adjust=False
确保权重总和始终为1,即不进行比例调整。iloc[-1]
用于获取每个窗口计算后的最后一个(即最新的)EMA值。
请注意,这种方法并不是标准的扩张窗口EMA计算方式,因为通常EMA不会在扩张窗口上这样计算。标准的EMA计算会使用固定的alpha
值,并且每个新值都会基于前一个EMA值和当前值来计算。如果你想要的是标准的EMA,你可以简单地使用ewm
方法,而不需要迭代窗口大小。
如果你确实想要每个扩张窗口结束时的某种“平均值”,那么上面的代码将为你提供这样的值,尽管它们不是传统意义上的EMA。
在不使用循环迭代的情况下计算扩张窗口的指数移动平均值(EMA)是有挑战性的,因为EMA本质上是一个递归过程,通常涉及迭代地应用权重。然而,我们可以通过矩阵运算和一些线性代数的技巧来避免显式的循环。
对于扩张窗口的EMA,我们没有一个直接的公式或内置函数可以一次性计算所有窗口的EMA,因为每个窗口大小对应不同的alpha值。但是,如果我们接受一定的近似,或者如果我们愿意为所有窗口使用相同的alpha值,那么我们可以使用ewm
方法而不进行迭代。
以下是一个使用相同alpha值计算所有扩张窗口EMA的近似方法的例子:
import pandas as pd
# 定义Series
s = pd.Series([1, 3, 6, 10])
# 选择一个alpha值,这里我们简单地使用1/(len(s)+1)作为近似
alpha = 1 / (len(s) + 1)
# 使用ewm方法计算EMA
ema = s.ewm(alpha=alpha, adjust=False).mean()
print(ema)
请注意,这种方法并不完全符合扩张窗口EMA的定义,因为它使用了固定的alpha值,而不是根据窗口大小动态调整的alpha值。因此,结果将是一个近似值,而不是精确的扩张窗口EMA。
如果你需要精确的扩张窗口EMA,并且不想使用循环,你可能需要借助更高级的数学工具,比如矩阵指数或特殊函数,这通常超出了标准数据分析库的范围,并且可能需要自定义实现或调用专门的数学库。
在实践中,对于不是很大的数据集,使用循环迭代来计算扩张窗口EMA通常是可行且简单的解决方案,尽管它可能不是最高效的方法。如果你关心性能,并且数据集很大,那么可能需要考虑更复杂的算法优化或使用并行处理技术。
df.expanding().apply(
lambda x: x.ewm(span=len(x), adjust=False).mean().to_numpy()[-1])