Уменьшите интервал данных pandas до таблицы с 12-месячными х 24-часовыми совокупными значениями - PullRequest
2 голосов
/ 08 апреля 2019

Я работаю с данными интервала счетчика коммунальных услуг, которые состоят из временной метки (обычно с шагом 1 час или 15 минут) и значения энергопотребления (в кВт или кВтч). Я хотел бы быстро преобразовать кадр данных pandas с индивидуальными показаниями в годовой сводный отчет со средними значениями, максимальными значениями и подсчетами за месяц, за час.

Формат годовой сводки будет 12-месячной x 24-часовой таблицей (288 отдельных ячеек), где каждая ячейка представляет собой либо среднее, максимальное, либо количество всех значений из этого конкретного месяца и часа.

Чтобы упростить задачу, давайте просто посмотрим на подсчет числа. (Из предложений я могу сделать вывод о выполнении аналогичных расчетов для средних и максимальных значений.)

Я попытался использовать метод грубой силы, отфильтровывая временные метки по месяцам и часам (цикл из 288 значений) и табулируя счетчики в матрице. Однако этот подход кажется очень медленным, поскольку я выполняю эти вычисления даже на 20 метрах. Мне любопытно, есть ли более быстрый способ достичь этого, используя панд / numpy.

Ниже приведен пример форматирования данных интервала.

from datetime import datetime
import pandas as pd

df = pd.DataFrame()
df["start"] = pd.date_range(start=datetime(2018, 1, 1), end=datetime(2018, 12, 31, 23), freq='900S')
df["value"] = 1
df.set_index("start", inplace=True)

В настоящее время я выполняю расчеты по следующим строкам:

for month in range(1, 13):
    for hour in range(0, 24):
        count = df.query("index.dt.month == {} and index.dt.hour == {}".format(month, hour)).count()

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

     1    2    3    4    5    6    7    8    9    10   11   12
0   124  112  124  120  124  120  124  124  120  124  120  124
1   124  112  124  120  124  120  124  124  120  124  120  124
2   124  112  124  120  124  120  124  124  120  124  120  124
3   124  112  124  120  124  120  124  124  120  124  120  124
4   124  112  124  120  124  120  124  124  120  124  120  124
5   124  112  124  120  124  120  124  124  120  124  120  124
6   124  112  124  120  124  120  124  124  120  124  120  124
7   124  112  124  120  124  120  124  124  120  124  120  124
8   124  112  124  120  124  120  124  124  120  124  120  124
9   124  112  124  120  124  120  124  124  120  124  120  124
10  124  112  124  120  124  120  124  124  120  124  120  124
11  124  112  124  120  124  120  124  124  120  124  120  124
12  124  112  124  120  124  120  124  124  120  124  120  124
13  124  112  124  120  124  120  124  124  120  124  120  124
14  124  112  124  120  124  120  124  124  120  124  120  124
15  124  112  124  120  124  120  124  124  120  124  120  124
16  124  112  124  120  124  120  124  124  120  124  120  124
17  124  112  124  120  124  120  124  124  120  124  120  124
18  124  112  124  120  124  120  124  124  120  124  120  124
19  124  112  124  120  124  120  124  124  120  124  120  124
20  124  112  124  120  124  120  124  124  120  124  120  124
21  124  112  124  120  124  120  124  124  120  124  120  124
22  124  112  124  120  124  120  124  124  120  124  120  124
23  124  112  124  120  124  120  124  124  120  124  120  124

Ответы [ 2 ]

4 голосов
/ 08 апреля 2019

Вы можете использовать pandas.crosstab, затем при необходимости используйте DataFrame.rename_axis для удаления имен осей в соответствии с желаемым выходом.

df_new = (pd.crosstab(df.index.hour, df.index.month)
          .rename_axis(None)
          .rename_axis(None, axis=1))

[выход]

     1    2    3    4    5    6    7    8    9    10   11   12
0   124  112  124  120  124  120  124  124  120  124  120  124
1   124  112  124  120  124  120  124  124  120  124  120  124
2   124  112  124  120  124  120  124  124  120  124  120  124
3   124  112  124  120  124  120  124  124  120  124  120  124
4   124  112  124  120  124  120  124  124  120  124  120  124
5   124  112  124  120  124  120  124  124  120  124  120  124
6   124  112  124  120  124  120  124  124  120  124  120  124
7   124  112  124  120  124  120  124  124  120  124  120  124
8   124  112  124  120  124  120  124  124  120  124  120  124
9   124  112  124  120  124  120  124  124  120  124  120  124
10  124  112  124  120  124  120  124  124  120  124  120  124
11  124  112  124  120  124  120  124  124  120  124  120  124
12  124  112  124  120  124  120  124  124  120  124  120  124
13  124  112  124  120  124  120  124  124  120  124  120  124
14  124  112  124  120  124  120  124  124  120  124  120  124
15  124  112  124  120  124  120  124  124  120  124  120  124
16  124  112  124  120  124  120  124  124  120  124  120  124
17  124  112  124  120  124  120  124  124  120  124  120  124
18  124  112  124  120  124  120  124  124  120  124  120  124
19  124  112  124  120  124  120  124  124  120  124  120  124
20  124  112  124  120  124  120  124  124  120  124  120  124
21  124  112  124  120  124  120  124  124  120  124  120  124
22  124  112  124  120  124  120  124  124  120  124  120  124
23  124  112  124  120  124  120  124  124  120  124  120  124
1 голос
/ 08 апреля 2019

Я бы использовал групповой вызов, затем развернул:

In [11]: res = df.groupby([df.index.month, df.index.hour])["value"].sum().unstack(0, fill_value=0)

In [12]: res.columns.name = "month"  # or None to suppress

In [13]: res.index.name = "hour"  # or None to suppress

In [14]: res
Out[44]:
month   1    2    3    4    5    6    7    8    9    10   11   12
hour
0      124  112  124  120  124  120  124  124  120  124  120  124
1      124  112  124  120  124  120  124  124  120  124  120  124
2      124  112  124  120  124  120  124  124  120  124  120  124
3      124  112  124  120  124  120  124  124  120  124  120  124
4      124  112  124  120  124  120  124  124  120  124  120  124
5      124  112  124  120  124  120  124  124  120  124  120  124
6      124  112  124  120  124  120  124  124  120  124  120  124
7      124  112  124  120  124  120  124  124  120  124  120  124
8      124  112  124  120  124  120  124  124  120  124  120  124
9      124  112  124  120  124  120  124  124  120  124  120  124
10     124  112  124  120  124  120  124  124  120  124  120  124
11     124  112  124  120  124  120  124  124  120  124  120  124
12     124  112  124  120  124  120  124  124  120  124  120  124
13     124  112  124  120  124  120  124  124  120  124  120  124
14     124  112  124  120  124  120  124  124  120  124  120  124
15     124  112  124  120  124  120  124  124  120  124  120  124
16     124  112  124  120  124  120  124  124  120  124  120  124
17     124  112  124  120  124  120  124  124  120  124  120  124
18     124  112  124  120  124  120  124  124  120  124  120  124
19     124  112  124  120  124  120  124  124  120  124  120  124
20     124  112  124  120  124  120  124  124  120  124  120  124
21     124  112  124  120  124  120  124  124  120  124  120  124
22     124  112  124  120  124  120  124  124  120  124  120  124
23     124  112  124  120  124  120  124  124  120  124  120  124

Примечание: я получаю разные значения, я получаю ~ 120, так как 4 раза в час умножается на количество дней в каждом месяце (одни месяцы длиннее других) ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...