group_by с Impala Ibis

У меня есть таблица Impala, которую я хотел бы запросить с помощью Ibis. Таблица выглядит следующим образом:

   id  | timestamp
-------------------
 A     | 5
 A     | 7
 A     | 3
 B     | 9
 B     | 5

Я хочу group_by изменить эту таблицу в соответствии с уникальными комбинациями id и timestamp range. В конечном итоге операция группировки должна создать один grouped объект, к которому я затем могу применить агрегирование. Например:

условия группы1: id == A; 4 < timestamp < 11
условия группы2: id == A; 1 < timestamp < 6
условия группы3: id == B; 4 < timestamp < 7

с получением объекта grouped со следующими группами:

группа 1:

   id  | timestamp
-------------------
 A     | 5
 A     | 7

группа2:

   id  | timestamp
-------------------
 A     | 5
 A     | 3

group3:

   id  | timestamp
-------------------
 B     | 5

Когда у меня будут группы, я проведу различные агрегаты, чтобы получить окончательные результаты. Если бы кто-нибудь мог помочь мне разобраться в этом group_by, я был бы очень признателен, даже регулярное выражение pandas было бы полезным!


person DavidS    schedule 20.10.2015    source источник


Ответы (1)


Итак, вот пример для groupby (без подчеркивания):

df = pd.DataFrame({"id":["a","b","a","b","c","c"], "timestamp":[1,2,3,4,5,6]})

создайте столбец группировщика для вашего timestamp.

df["my interval"] = (df["timestamp"] > 3 )&  (df["timestamp"] <5)
"you need some _data_ columns, i.e. those which you do not use for grouping"
df["dummy"] = 1 
df.groupby(["id", "my interval"]).agg("count")["dummy"]

Или вы можете использовать оба:

df["something that I need"] = df["my interval"] & (df["id"] == "b")
df.groupby(["something that I need"]).agg("count")["dummy"]

вы также можете применить целочисленное деление для генерации временных интервалов:

df = pd.DataFrame({"id":["a","b","a","b","c","c"], "timestamp":[1,2,13,14,25,26], "sales": [0,4,2,3,6,7]})
epoch = 10
df["my interval"] = epoch* (df["timestamp"] // epoch)
df.groupby(["my interval"]).agg(sum)["sales"]

РЕДАКТИРОВАТЬ:

ваш пример:

import pandas as pd
A = "A"
B = "B"
df = pd.DataFrame({"id":[A,A,A,B,B], "timestamp":[5,7,3,9,5]})
df["dummy"] = 1

Решение:

grouper = (df["id"] == A) & (4 < df["timestamp"] ) & ( df["timestamp"] < 11)
df.groupby( grouper ).agg(sum)["dummy"]

или лучше:

df[grouper]["dummy"].sum()
person Dima Lituiev    schedule 24.10.2015
comment
Привет Дима, спасибо за ответ. Проблема, с которой я столкнулся, заключается в создании нескольких, иногда перекрывающихся интервалов времени, которые применяются только к определенным ids. Если вы попытаетесь создать группы из моего примера, вы поймете, что я имею в виду. В качестве примечания: у pandas есть удобная удобная функция для группировки по значениям бинов, называемая pd.cut. - person DavidS; 25.10.2015
comment
если у вас есть перекрывающиеся интервалы, вам понадобится несколько groupby операций или, что более эффективно, вы можете использовать логическое индексирование. См. Последнее изменение - person Dima Lituiev; 25.10.2015
comment
Как я уже упоминал, проблема состоит в том, чтобы создать все группы с одним groupby. Опять же, попробуйте решить весь пример, и вы оцените сложность задачи. - person DavidS; 25.10.2015
comment
Представьте, что царь Саломон группирует младенца по его матери, и вы поймете, что проблема действительно фундаментальна. Если вы хотите разбить конечный набор на конечное количество подмножеств, вы не можете включить один элемент исходного подмножества в несколько групп. - person Dima Lituiev; 25.10.2015
comment
Groupby работает с метками, то есть вы даете каждому элементу метку, которая сопоставляет его с подмножеством. У вас может не быть двух меток, которые сопоставляют один элемент с несколькими подмножествами. - person Dima Lituiev; 25.10.2015
comment
если вы действительно верите, что это единственный способ, вам нужно будет разрезать своих младенцев пополам, то есть разработать схему для дублирования ваших строк. - person Dima Lituiev; 25.10.2015
comment
и обратите внимание, что pd.cut также возвращает неперекрывающиеся интервалы. Таким образом, в вашем случае это эквивалентно целочисленному делению. - person Dima Lituiev; 25.10.2015
comment
К сожалению, у меня нет возможности дублировать строки, мой фактический набор данных находится в таблице Impala, распределенной в кластере, и потенциально имеет размер несколько ТБ. Кроме того, я не имел в виду, что pd.cut может создавать перекрывающиеся наборы, просто это был элегантный способ группировки по корзине. В любом случае, спасибо за ваши усилия. - person DavidS; 25.10.2015
comment
мое решение решение вашей проблемы? если да, пожалуйста, проголосуйте за. - person Dima Lituiev; 25.10.2015
comment
Извините, ваше решение никоим образом не решает мою проблему. - person DavidS; 25.10.2015