ТБ, я не совсем уверен, как задать этот вопрос. У меня есть массив значений, и я ищу, чтобы сгладить среднее значение этих значений, продвигаясь вперед. В Excel процесс расчета:
и т.д.
В pandas и numpy мой код для этого следующий
df = pd.DataFrame({'av':np.nan, 'values':np.random.rand(10)})
df = df[['values','av']]
window = 5
df['av'].iloc[5] = np.mean(df['values'][:5])
for i in range(window+1,len(df.index)):
df['av'].iloc[i] = (df['values'].iloc[i] * (window-1) + df['av'].iloc[i-1])/window
Что возвращает:
values av
0 0.418498 NaN
1 0.570326 NaN
2 0.296878 NaN
3 0.308445 NaN
4 0.127376 NaN
5 0.381160 0.344305
6 0.239725 0.260641
7 0.928491 0.794921
8 0.711632 0.728290
9 0.319791 0.401491
Это значения, которые я ищу, но должен быть лучший способ, чем использовать для циклов. Я думаю, что ответ имеет какое-то отношение к использованию экспоненциально взвешенных скользящих средних, но я буду проклят, если смогу понять синтаксис, чтобы понять это.
Какие-либо предложения?
вы можете использовать ewm, например:
window = 5
df['av'] = np.nan
df['av'].iloc[window] = np.mean(df['values'][:window])
df.loc[window:,'av'] = (df.loc[window:,'av'].fillna(df['values'])
.ewm(adjust=False, alpha=(window-1.)/window).mean())
и вы получите тот же результат, чем с петлей for
. Для того, чтобы убедиться, что она работает, колонка "ау" должна быть nan
иначе fillna
с колонкой "значениями" не будет, а значение calculted в "ау" будет неправильно. Параметр alpha
в ewm
- это то, что помогает вам подсчитывать строку, которую вы вычисляете.
Примечание: хотя этот код работает как ваш, я бы рекомендовал взглянуть на эту строку в вашем коде:
df['av'].iloc[5] = np.mean(df['values'][:5])
Из-за исключения вершинной привязки при выполнении нарезки [:5]
df['values'][:5]
:
0 0.418498
1 0.570326
2 0.296878
3 0.308445
4 0.127376
Name: values, dtype: float64
поэтому я думаю, что вам нужно сделать df['av'].iloc[4] = np.mean(df['values'][:5])
. Если вы согласитесь, то мое выше должно быть слегка изменено
df['av'].iloc[window-1] = np.mean(df['values'][:window])
df.loc[window-1:,'av'] = (df.loc[window-1:,'av'].fillna(df['values'])
.ewm(adjust=False, alpha=(window-1.)/window).mean())