Как конвертировать ежемесячные данные ежеквартально в pandas

У меня есть месячные данные. Я хочу преобразовать его в "периоды" по 3 месяца, где в январе начинается 1 квартал. Таким образом, в приведенном ниже примере агрегация за первые 3 месяца будет преобразована в начало q2 (желаемый формат: 1996q2). И значение данных, которое получается в результате слияния трех месячных значений, представляет собой среднее (среднее) из трех столбцов. Концептуально не сложно. Кто-нибудь знает, как это сделать одним махом? Потенциально, я мог бы сделать много тяжелой работы с помощью циклов и просто жестко закодировать его, но я новичок в пандах и ищу что-то более умное, чем грубая сила.

1996-04   1996-05 1996-06  1996-07 .....
25          19       37      40

Поэтому я ищу:

1996q2  1996q3   1996q4  1997q1  1997q2 .....
 avg      avg      avg     ...     ...

Ответ 1

Вы можете использовать pd.PeriodIndex(..., freq = 'Q') в сочетании с groupby (..., axis = 1):

In [63]: df
Out[63]:
   1996-04  1996-05  2000-07  2000-08  2010-10  2010-11  2010-12
0        1        2        3        4        1        1        1
1       25       19       37       40        1        2        3
2       10       20       30       40        4        4        5

In [64]: df.groupby(pd.PeriodIndex(df.columns, freq='Q'), axis=1).mean()
Out[64]:
   1996Q2  2000Q3    2010Q4
0     1.5     3.5  1.000000
1    22.0    38.5  2.000000
2    15.0    35.0  4.333333

ОБНОВЛЕНИЕ: чтобы получить столбцы в результирующем DF в виде строк типа intead period dtype:

In [66]: res = (df.groupby(pd.PeriodIndex(df.columns, freq='Q'), axis=1)
                  .mean()
                  .rename(columns=lambda c: str(c).lower()))

In [67]: res
Out[67]:
   1996q2  2000q3    2010q4
0     1.5     3.5  1.000000
1    22.0    38.5  2.000000
2    15.0    35.0  4.333333

In [68]: res.columns.dtype
Out[68]: dtype('O')

Ответ 2

@MAxU. Я знаю, что здесь только для ответа на вопрос. Однако мне не хватает очков репутации, чтобы оставлять свои комментарии. Извини за это. Поскольку я очень плохо знаком с Python и Pandas, было бы здорово, если бы вы могли дать больше объяснений кодам, которые вы написали выше.

res = (df.groupby(pd.PeriodIndex(df.columns, freq = 'Q'), axis = 1) В частности 1) Работает ли pd.PeriodIndex как с именами столбцов строки, так и с меткой времени? В документации написано, что data: array-like... так что я думаю, да? 2) Я пытался использовать ваши коды на фрейме данных с ежемесячными столбцами, а также с другими столбцами, которые содержат строковые/логические значения. поэтому вместо df.columns я использовал df.columns [6:], но получил сообщение об ошибке Assertionerror: Grouper и axis должны быть одинаковой длины. Знаете ли вы, почему возникает эта ошибка? И как выбрать только месячные столбцы, чтобы этот кусок кода работал?

большое спасибо