Применение экспоненциально-взвешенного среднего Python Pandas в обратном порядке

Для примера pandas.DataFrame:

In: cols = ['cols1', 'cols2']
In: df = pd.DataFrame({'col1': [1, 2, 3, 4], 'col2': [3, 4, 5, 6]})

Out:       col1  col2
      0     1     3
      1     2     4
      2     3     5
      3     4     6

Я использую экспоненциально-взвешенное среднее:

In: for i in range(len(df.columns)):
       df[cols[i]] = df[cols[i]].ewm(com=None, span=None, halflife=None, 
                                     alpha=.8, min_periods=0, adjust=True,
                                     ignore_na=False, axis=0).mean()

Это прекрасно работает! Однако веса применяются с экспоненциально уменьшающимися значениями сверху вниз:

  Out:      col1      col2
      0  1.000000  3.000000
      1  1.833333  3.833333
      2  2.774194  4.774194
      3  3.756410  5.756410

Мне интересно, есть ли способ применить веса в обратном порядке (снизу вверх). Мой желаемый результат:

Out:          col1          col2
      0     0.9391025     2.8173075
      1     1.8494627     3.6982925
      2     2.7499995     4.5833325
      3     4.000000      6.000000

person kel    schedule 07.06.2018    source источник
comment
Можете ли вы опубликовать желаемый результат?   -  person user3483203    schedule 07.06.2018
comment
Я добавил желаемый результат. Я просто хочу, чтобы веса применялись в обратном порядке к данным. Мои наиболее важные данные находятся внизу таблицы, поэтому я хочу, чтобы они имели наибольший вес.   -  person kel    schedule 07.06.2018


Ответы (2)


Я нашел решение проблемы. Вы можете переиндексировать до и после применения ewm():

In: df.reindex(index=df.index[:-1])
    for i in range(len(df.columns)):
        df[cols[i]] = df[cols[i]].ewm(com=None, span=None, halflife=None, 
                                      alpha=.8, min_periods=0, adjust=True,
                                      ignore_na=False, axis=0).mean()
Out:        col1      col2
      3  4.000000  6.000000
      2  3.166667  5.166667
      1  2.225806  4.225806
      0  1.243590  3.243590

Затем вы можете применить его снова:

In: df.reindex(index=df.index[:-1])
Out:        col1      col2
       0  1.243590  3.243590
       1  2.225806  4.225806
       2  3.166667  5.166667
       3  4.000000  6.000000

Я до сих пор не уверен, что это самый эффективный метод. Так что, если у кого-то есть другие идеи, я хотел бы знать.

person kel    schedule 07.06.2018

Вариант решения kel.

Обратите внимание, что

df[col].reindex(index=df.index[::-1])

достигает такого же результата, как:

df[col].sort_index(ascending=False)

Одно отличие состоит в том, что reindex изменяет индекс на месте, а sort_index принимает inplace в качестве опции. В результате преимущество sort_index заключается в том, что вам не нужно переключаться обратно в конце, в отличие от reindex:

df[col] = df[col].sort_index(ascending=False).ewm(...).mean()

Обратите также внимание, что решение с sort_index, конечно же, предполагает, что значения индекса упорядочены в правильном порядке. Если это не так, я не уверен, что скользящее среднее имеет физический смысл.

person Antoine    schedule 12.04.2019
comment
Еще более простым решением было бы использование нарезки: df[::-1][col].ewm(...).mean(). Я не сравнивал относительные скорости. - person Antoine; 12.04.2019