Как зациклить группировку данных Pandas по иерархическому мультииндексу сверху вниз и сохранить результаты - PullRequest
2 голосов
/ 29 марта 2019

Я пытаюсь создать процесс прогнозирования, используя иерархические временные ряды.Моя проблема в том, что я не могу найти способ создать цикл for, который иерархически извлекает дневные временные ряды из кадра данных pandas, группирующего сумму количеств по дате.Полученный дневной временной ряд должен быть передан в функцию внутри цикла, а результаты сохранены в другом объекте.

Набор данных

Исходный набор данных представляет собой таблицу, которая представляет данные ежедневных продаж3 иерархических уровня: город, магазин, продукт.Исходная таблица имеет такую ​​структуру:

+============+============+============+============+==========+
| Id_Level_1 | Id_Level_2 | Id_Level_3 |    Date    | Quantity |
+============+============+============+============+==========+
| Rome       | Shop1      | Prod1      | 01/01/2015 |       50 |
+------------+------------+------------+------------+----------+
| Rome       | Shop1      | Prod1      | 02/01/2015 |       25 |
+------------+------------+------------+------------+----------+
| Rome       | Shop1      | Prod1      | 03/01/2015 |       73 |
+------------+------------+------------+------------+----------+
| Rome       | Shop1      | Prod1      | 04/01/2015 |       62 |
+------------+------------+------------+------------+----------+
| ...        | ...        | ...        | ...        |      ... |
+------------+------------+------------+------------+----------+
| Milan      | Shop3      | Prod9      | 31/12/2018 |      185 |
+------------+------------+------------+------------+----------+
| Milan      | Shop3      | Prod9      | 31/12/2018 |      147 |
+------------+------------+------------+------------+----------+
| Milan      | Shop3      | Prod9      | 31/12/2018 |      206 |
+------------+------------+------------+------------+----------+

В каждом городе (Id_Level_1) есть много магазинов (Id_Level_2), и у каждого есть несколько продуктов (Id_Level_3).Каждый магазин имеет различное сочетание продуктов (возможно, shop1 и shop3 имеют product7, которого нет в других магазинах).Все данные являются ежедневными, а мера интереса - это количество.

Иерархический индекс (MultiIndex)

Мне нужно создать древовидную структуру (иерархическую структуру), чтобы извлечь временной ряд для каждого "узла"структуры.Я называю «узел» комбинацией иерархических ключей, то есть «Рим» и «Милан» являются узлами уровня 1, а «Рим | Магазин1» и «Милан | Магазин9» являются узлами уровня 2. В частности, мне нужноэто на уровне 3, потому что каждый продукт (Id_Level_3) имеет разные продажи в каждом магазине каждого города.Здесь строгая иерархия.Узлами уровня 3 являются «Рим, Магазин1, Прод1», «Рим, Магазин1, Прод2», «Рим, Магазин2, Прод1» и т. Д.Ключом узлов является логическое объединение идентификаторов.

Для каждого узла временной ряд состоит из двух столбцов: Дата и Количество.

# MultiIndex dataframe
Liv_Labels = ['Id_Level_1', 'Id_Level_2', 'Id_Level_3', 'Date']
df.set_index(Liv_Labels, drop=False, inplace=True)

Мне нужно извлечьагрегированные временные ряды в порядке, но с сохранением иерархических узлов.

Уровень 0:

Level_0 = df.groupby(level=['Data'])['Qta'].sum()

Уровень 1:

# Node Level 1 "Rome"
Level_1['Rome'] = df.loc[idx[['Rome'],:,:]].groupby(level=['Data']).sum()

# Node Level 1 "Milan"
Level_1['Milan'] = df.loc[idx[['Milan'],:,:]].groupby(level=['Data']).sum()

Уровень 2:

# Node Level 2 "Rome, Shop1"
Level_2['Rome',] = df.loc[idx[['Rome'],['Shop1'],:]].groupby(level=['Data']).sum()

... repeat for each level 2 node ...

# Node Level 2 "Milan, Shop9"
Level_2['Milan'] = df.loc[idx[['Milan'],['Shop9'],:]].groupby(level=['Data']).sum()

Попытки

Я уже пытался создавать словари и мультииндекс, но моя проблема в том, что я не могу получить правильное "узел "использовать внутри цикла.Я даже не могу извлечь ключи узлов уникального уровня, поэтому не могу собрать определенный временной ряд узла.

# Get level labels
Level_Labels = ['Id_Liv'+str(n) for n in range(1, Liv_Num+1)]+['Data']

# Initialize dictionary
TimeSeries = {} 

# Get Level 0 time series
TimeSeries["Level_0"] = df.groupby(level=['Data'])['Qta'].sum()

# Get othe levels time series from 1 to Level_Num
for i in range(1, Liv_Num+1):
    TimeSeries["Level_"+str(i)] = df.groupby(level=Level_Labels[0:i]+['Data'])['Qta'].sum()

Желаемый результат

Я бы хотел зациклить циклы моего набора данныхс этими действиями:

  1. Создает структуру всех уникальных ключей узла.
  2. Извлекает временные ряды узлов, сгруппированные по дате и количеству.
  3. Сохраняет временные ряды в видеструктура для последующего использования

Заранее спасибо за любые предложения!С наилучшими пожеланиями.FR

1 Ответ

0 голосов
/ 29 мая 2019

В настоящее время я работаю с набором данных коммутатора, который я опрашивал из базы данных sql, где каждый порт на соответствующем коммутаторе имеет фрейм данных, который имеет временной ряд. Таким образом, чтобы получить доступ к информации о временных рядах для каждого конкретного порта, я представлял коммутаторы по их IP-адресам и разному количеству портов на коммутаторе, а также чтобы убедиться, что я не перезапрошу то, что уже запрашивал, прежде чем использовать .unique. () метод для получения уникальных запросов каждого.

Я установил свой индекс на индексы IP и порта и получил доступ к информации о порте следующим образом:

def yield_df(df):
for ip in df.index.get_level_values('ip').unique():
    for port in df.loc[ip].index.get_level_values('port').unique():
        yield df.loc[ip].loc[port]

Затем я зациклил фреймы данных порта с помощью цикла for, например:

for port_df in yield_df(adb_df):

Я уверен, что есть более быстрые способы выполнения этих процедур в пандах, но я надеюсь, что это поможет вам начать решать вашу проблему

...