Есть ли способ заставить Pandas ewm работать на фиксированных окнах? - PullRequest
1 голос
/ 19 сентября 2019

Я пытаюсь использовать функцию Pandas ewm для расчета экспоненциально взвешенных скользящих средних.Однако я заметил, что информация, кажется, пронизывает весь ваш временной ряд.Это означает, что MA каждой точки данных зависит от разного количества предыдущих точек данных.Поэтому функция ewm в каждой точке данных математически отличается.

Я думаю, что у некоторых здесь был похожий вопрос

Неужели Панды неправильно вычислили ewm?

Но я попробовал их метод, и я не получаю нужную функциональность.

 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 действительно зависит от всей серии.

1 Ответ

1 голос
/ 19 сентября 2019

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

Вывод: мы видим, что большее окно (зеленое) менее изменчиво, чем меньшее окно (оранжевое).

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...