pandas - как получить последние n групп объекта groupby и объединить их как dataframe

Как получить последние 'n' группы после df.groupby() и объединить их в качестве фрейма данных.

data = pd.read_sql_query(sql=sqlstr, con=sql_conn, index_col='SampleTime')
grouped = data.groupby(data.index.date,sort=False)

После выполнения grouped.ngroups я получаю общее количество групп 277. Я хочу объединить последние 12 групп и создать фрейм данных.

Ответ 1

Объекты Pandas GroupBy являются итерабельными. Чтобы извлечь последние n элементов итерации, вообще нет необходимости создавать список из итерируемого и срезать последние n элементов. Это будет дорого стоить.

Вместо этого вы можете использовать либо itertools.islice (как предложено @mtraceur), либо collections.deque. Оба работают в O (n) времени.

itertools.islice

В отличие от генератора объект Pandas GroupBy является итерабельным, который можно использовать повторно. Поэтому вы можете рассчитать количество групп через len(g) для объекта GroupBy g а затем отрезать g через islice. Или, возможно, более идиоматично, вы можете использовать GroupBy.ngroups. Затем используйте pd.concat для объединения итерации в числовые кадры:

from operator import itemgetter

g = data.groupby(data.index.date, sort=False)
res = pd.concat(islice(map(itemgetter(1), g), max(0, g.ngroups-12), None))

collections.deque

Кроме того, вы можете использовать collections.deque и указать maxlen, а затем конкатенировать, как и раньше.

from collections import deque

grouped = data.groupby(data.index.date, sort=False)
res = pd.concat(deque(map(itemgetter(1), grouped), maxlen=12))

Как описано в документах collections:

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

Ответ 2

Предполагая, что вы знаете порядок grouped

grouped = zip(*df.groupby(data.index.date,sort=False))
pd.concat(list(grouped)[1][-12:])

Ответ 3

используйте pd.concat для понимания списков и groupby.get_group

pd.concat([grouped.get_group(x) for x in list(grouped.groups.keys())[-12:]])

Ответ 4

Вы можете передать список pd.concat():

import pandas as pd

df = pd.DataFrame([
['A',1,2],
['A',7,6],
['B',1,3],
['B',9,9],
['C',1,8],
['A',4,3],
['C',7,6],
['D',4,2]],
columns=['Var','Val1','Val2'])

last_n = 2
grouped = df.groupby('Var')

pd.concat([grouped.get_group(group) for i, group in enumerate(grouped.groups) if i>=len(grouped)-last_n])

Урожайность:

  Var  Val1  Val2
4   C     1     8
6   C     7     6
7   D     4     2