web-dev-qa-db-fra.com

pandas - comment obtenir les n derniers groupes d’un objet groupby et les combiner en tant que cadre de données

Comment obtenir les n derniers groupes après df.groupby() et les combiner en tant que base de données. 

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

Après avoir fait grouped.ngroups, je reçois le nombre total de groupes 277. Je souhaite combiner les 12 derniers groupes et générer un cadre de données.

12
stockade

Les objets Pandas GroupBy sont iterables. Pour extraire les derniers éléments n d'un élément itérable, il n'est généralement pas nécessaire de créer une liste à partir de l'élément itérable et de trancher les derniers éléments n. Ce sera coûteux en mémoire.

Au lieu de cela, vous pouvez utiliser itertools.islice (comme suggéré par @mtraceur) ou collections.deque. Les deux fonctionnent en temps O (n).

itertools.islice

Contrairement à un générateur, un objet Pandas GroupBy est un objet itérable qui peut être réutilisé. Par conséquent, vous pouvez calculer le nombre de groupes via len(g) pour un objet GroupBy et g, puis découpez g via islice. Ou, peut-être plus idiomatique, vous pouvez utiliser GroupBy.ngroups. Puis utilisez pd.concat pour concaténer un iterable de dataframes:

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

Vous pouvez également utiliser collections.deque et spécifier maxlen, puis concaténer comme auparavant.

from collections import deque

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

Comme décrit dans la documentation collections:

Une fois que la longueur liée deque est pleine, lorsque de nouveaux éléments sont ajoutés, un le nombre correspondant d'éléments est éliminé à partir de l'extrémité opposée .... Ils sont également utiles pour suivre les transactions et autres groupes de données où seule l'activité la plus récente présente un intérêt.

9
jpp

En supposant que vous connaissiez l'ordre de grouped

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

utiliser pd.concat sur la compréhension des listes et groupby.get_group

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

Vous pouvez passer une compréhension de liste à 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])

Rendements:

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