Эффективная агрегация по времени индекса в Пандах - PullRequest
0 голосов
/ 15 октября 2018

У меня есть данные в недельном формате, которые я хочу агрегировать до месячного уровня эффективным способом.В настоящее время я делаю переиндексацию DataFrame от недели к дням, а затем принимаю среднее значение по дням в каждом месяце.Этот подход медленный, особенно когда я имею дело с большими данными.Я ищу более эффективный способ.

Упрощенный пример

Недельные данные:

dates = ['2018-8-20','2018-8-27','2018-9-10']
values = [1,2,3]

df = pd.Series(values, index=pd.to_datetime(dates))
df.index.name = 'week'
df.name = 'val'

Превратился в ежедневный (обратите внимание, что япрямое заполнение нулями):

date_list = [df.index.min() + datetime.timedelta(days=x) for x in range(0, (df.index.max()-df.index.min()).days+1)]
dfDaily = df.reindex(date_list)
dfDaily=  dfDaily.fillna(method='ffill')

dfDaily = pd.DataFrame(dfDaily)
dfDaily['month'] = dfDaily.index.month
dfDaily['year'] = dfDaily.index.year

, что дает:

            val  month  year
week                        
2018-08-20  1.0      8  2018
2018-08-21  1.0      8  2018
2018-08-22  1.0      8  2018
2018-08-23  1.0      8  2018
2018-08-24  1.0      8  2018
2018-08-25  1.0      8  2018
2018-08-26  1.0      8  2018
2018-08-27  2.0      8  2018
2018-08-28  2.0      8  2018
2018-08-29  2.0      8  2018
2018-08-30  2.0      8  2018
2018-08-31  2.0      8  2018
2018-09-01  2.0      9  2018
2018-09-02  2.0      9  2018
2018-09-03  2.0      9  2018
2018-09-04  2.0      9  2018
2018-09-05  2.0      9  2018
2018-09-06  2.0      9  2018
2018-09-07  2.0      9  2018
2018-09-08  2.0      9  2018
2018-09-09  2.0      9  2018
2018-09-10  3.0      9  2018    

Агрегирование до месячного уровня:

dfMonthly = dfDaily.groupby(['year', 'month']).val.mean().reset_index()

, что приводит к желаемому кадру данных:;

   year  month       val
0  2018      8  1.416667
1  2018      9  2.100000

1 Ответ

0 голосов
/ 15 октября 2018

Вы можете упростить свое решение, но не уверены, что большое улучшение производительности:

date_list = pd.date_range(df.index.min(), df.index.max(), freq='d')
s = df.reindex(date_list, method='ffill')

dfDaily = s.groupby([s.index.year.rename('year'),
                     s.index.month.rename('month')]).mean().reset_index()
print (dfDaily)
   year  month       val
0  2018      8  1.416667
1  2018      9  2.100000
...