Получение среднего часа в будние дни в течение нескольких лет в кадре pandas

У меня есть часовой блок данных в следующем формате в течение нескольких лет:

Date/Time            Value
01.03.2010 00:00:00  60
01.03.2010 01:00:00  50
01.03.2010 02:00:00  52
01.03.2010 03:00:00  49
.
.
.
31.12.2013 23:00:00  77

Я хотел бы усреднить данные, чтобы получить среднее значение часа 0, час 1... час 23 каждого года.

Итак, результат должен выглядеть примерно так:

Year Hour           Avg
2010 00              63
2010 01              55
2010 02              50
.
.
.
2013 22              71
2013 23              80

Кто-нибудь знает, как получить это в pandas?

Ответ 1

Примечание. Теперь, когда у Series есть dt-аксессор, менее важно, что дата является индексом, хотя Date/Time все еще должно быть datetime64.

Обновление: вы можете сделать группу более напрямую (без лямбда):

In [21]: df.groupby([df["Date/Time"].dt.year, df["Date/Time"].dt.hour]).mean()
Out[21]:
                     Value
Date/Time Date/Time
2010      0             60
          1             50
          2             52
          3             49

In [22]: res = df.groupby([df["Date/Time"].dt.year, df["Date/Time"].dt.hour]).mean()

In [23]: res.index.names = ["year", "hour"]

In [24]: res
Out[24]:
           Value
year hour
2010 0        60
     1        50
     2        52
     3        49

Если это индекс datetime64, вы можете сделать:

In [31]: df1.groupby([df1.index.year, df1.index.hour]).mean()
Out[31]:
        Value
2010 0     60
     1     50
     2     52
     3     49

Старый ответ (будет медленнее):

Предполагая, что Date/Time является индексом *, вы можете использовать функцию отображения в groupby:

In [11]: year_hour_means = df1.groupby(lambda x: (x.year, x.hour)).mean()

In [12]: year_hour_means
Out[12]:
           Value
(2010, 0)     60
(2010, 1)     50
(2010, 2)     52
(2010, 3)     49

Для более полезного индекса вы можете создать MultiIndex из кортежей:

In [13]: year_hour_means.index = pd.MultiIndex.from_tuples(year_hour_means.index,
                                                           names=['year', 'hour'])

In [14]: year_hour_means
Out[14]:
           Value
year hour
2010 0        60
     1        50
     2        52
     3        49

* если нет, тогда сначала используйте set_index:

df1 = df.set_index('Date/Time')

Ответ 2

Если столбец даты/времени находился в формате даты и времени (см. dateutil.parser для параметров автоматического разбора), вы можете использовать повторную выборку pandas, как показано ниже:

year_hour_means = df.resample('H',how = 'mean')

который сохранит ваши данные в формате даты и времени. Это может помочь вам с тем, что вы собираетесь делать с вашими данными по линии.