Создание скользящего среднего годового цикла в pandas, python - PullRequest
0 голосов
/ 21 февраля 2020

Я пытаюсь использовать pandas для создания скользящего среднего, но годового цикла (чтобы скользящее среднее на 31 декабря учитывало значения с января, а скользящее среднее за январь использовало значения за декабрь ). Кто-нибудь знает, есть ли встроенный или другой элегантный способ сделать это?

Единственный способ, которым я до сих пор придумал, - это создать годовой цикл, а затем повторить его в течение високосных лет (поскольку годовой цикл включает в себя 29 февраля), взять скользящее среднее (или стандартное отклонение, et c), а затем обрезать середину года. Должно быть лучшее решение! Вот моя попытка:

import pandas as pd
import numpy as np
import calendar

data = np.random.rand(366)
df_annual_cycle = pd.DataFrame(
    columns=['annual_cycle'],
    index=pd.date_range('2004-01-01','2004-12-31').strftime('%m-%d'),
    data=data
)

df_annual_cycle.head()

#        annual_cycle
# 01-01      0.863838
# 01-02      0.234168
# 01-03      0.368678
# 01-04      0.066332
# 01-05      0.493080

df1 = df_annual_cycle.copy()
df1.index = ['04-'+x for x in df1.index]
df1.index = pd.to_datetime(df1.index,format='%y-%m-%d')
df2 = df.copy()
df2.index = ['08-'+x for x in df2.index]
df2.index = pd.to_datetime(df2.index,format='%y-%m-%d')
df3 = df.copy()
df3.index = ['12-'+x for x in df3.index]
df3.index = pd.to_datetime(df3.index,format='%y-%m-%d')

df_for_rolling = df1.append(df2).append(df3)
df_rolling = df_for_rolling.rolling(65).mean()
df_annual_cycle_rolling = df_rolling.loc['2008-01-01':'2008-12-31']
df_annual_cycle_rolling.index = df_annual_cycle.index

1 Ответ

0 голосов
/ 21 февраля 2020

Мы можем использовать pandas.DataFrame.rolling(). Подробности и другие методы прокрутки можно найти здесь: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rolling.html

Предположим, у нас есть такой фрейм данных:

data = np.concatenate([
    1*np.random.rand(366//6), 
    2*np.random.rand(366//6), 
    3*np.random.rand(366//6), 
    4*np.random.rand(366//6), 
    5*np.random.rand(366//6), 
    6*np.random.rand(366//6)
])

df_annual_cycle = pd.DataFrame(
    columns=['annual_cycle'],
    index=pd.date_range('2004-01-01','2004-12-31').strftime('%m-%d'),
    data=data,
)

Мы можем сделать:

# reset the index to integers:
df_annual_cycle = df_annual_cycle.reset_index()

# rename index column to date:
df_annual_cycle = df_annual_cycle.rename(columns={'index':'date'})

# calculate the rolling mean:
df_annual_cycle['rolling_mean'] = df_annual_cycle['annual_cycle'].rolling(32, win_type='triang').mean()

# plot results
df_annual_cycle.plot(x='date', y=['annual_cycle', 'rolling_mean'], style=['o', '-'])

Результат выглядит так:

enter image description here

...