【问题标题】:Is there a way to get Pandas ewm to function on fixed windows?有没有办法让 Pandas ewm 在固定窗口上运行?
【发布时间】:2020-01-20 13:22:52
【问题描述】:

我正在尝试使用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 个窗口。但是当我运行此代码时,我得到两个不同的值,表明 ewm 确实依赖于整个系列。

【问题讨论】:

    标签: python pandas moving-average weighted-average


    【解决方案1】:

    IIUC,您在滚动窗口中要求 ewm,这意味着每 10 行返回一个数字。如果是这样,那么我们可以使用步幅技巧:

    编辑:更新功能仅适用于系列

    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()
    

    输出:我们可以看到较大的窗口(绿色)比较小的窗口(橙色)的波动性更小。

    【讨论】:

    • 我实际上不太确定这是否是我正在寻找的。调整窗口看起来只是抵消数据,它不会增加单个移动平均线考虑的数据点数量。
    • 你确定吗? EMA(a,window=2).tail(10) 给出:98 98.7590 90.75
    • 调整窗口应该使数据平滑,但看起来只是抵消它。如果我对数据进行转换,我会看到它排成一行。
    • 您的数据是线性的,固定窗口上的移动平均值只会移动它。试试a = pd.DataFrame(np.random.uniform(0,3,100))上的代码。
    • @learningthemachine 查看更新。请注意,该功能现在仅适用于系列。
    猜你喜欢
    • 1970-01-01
    • 2014-03-22
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    相关资源
    最近更新 更多