211 votes

Comment accéder à un dataframe pandas groupby par clé ?

Comment accéder au dataframe groupby correspondant dans un objet groupby par la clé ?

Avec le groupby suivant :

rand = np.random.RandomState(1)
df = pd.DataFrame({'A': ['foo', 'bar'] * 3,
                   'B': rand.randn(6),
                   'C': rand.randint(0, 20, 6)})
gb = df.groupby(['A'])

Je peux itérer à travers elle pour obtenir les clés et les groupes :

In [11]: for k, gp in gb:
             print 'key=' + str(k)
             print gp
key=bar
     A         B   C
1  bar -0.611756  18
3  bar -1.072969  10
5  bar -2.301539  18
key=foo
     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14

Je voudrais pouvoir accéder à un groupe par sa clé :

In [12]: gb['foo']
Out[12]:  
     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14

Mais quand j'essaie de faire ça avec gb[('foo',)] Je reçois cette étrange pandas.core.groupby.DataFrameGroupBy qui ne semble pas avoir de méthodes correspondant au DataFrame que je veux.

Le mieux auquel je puisse penser est :

In [13]: def gb_df_key(gb, key, orig_df):
             ix = gb.indices[key]
             return orig_df.ix[ix]

         gb_df_key(gb, 'foo', df)
Out[13]:
     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14  

mais c'est plutôt désagréable, vu la gentillesse des pandas dans ce genre de situation.
Quel est le moyen intégré de faire cela ?

272voto

Andy Hayden Points 38010

Vous pouvez utiliser le get_group méthode :

In [21]: gb.get_group('foo')
Out[21]: 
     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14

Note : Cela ne nécessite pas de créer un dictionnaire intermédiaire / une copie de chaque sous-trame de données pour chaque groupe, et sera donc beaucoup plus efficace en termes de mémoire que de créer le dictionnaire naïf avec dict(iter(gb)) . Cela est dû au fait qu'il utilise des structures de données déjà disponibles dans l'objet groupby.


Vous pouvez sélectionner différentes colonnes en utilisant le découpage groupby :

In [22]: gb[["A", "B"]].get_group("foo")
Out[22]:
     A         B
0  foo  1.624345
2  foo -0.528172
4  foo  0.865408

In [23]: gb["C"].get_group("foo")
Out[23]:
0     5
2    11
4    14
Name: C, dtype: int64

87voto

JD Margulici Points 203

Wes McKinney (auteur de pandas) dans Python for Data Analysis fournit la recette suivante :

groups = dict(list(gb))

qui renvoie un dictionnaire dont les clés sont vos étiquettes de groupe et dont les valeurs sont des DataFrames, c'est-à-dire

groups['foo']

vous donnera ce que vous cherchez :

     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14

1 votes

Merci, c'est très utile. Comment puis-je modifier le code pour que groups = dict(list(gb)) uniquement la colonne de stockage C ? Disons que les autres colonnes ne m'intéressent pas et que je ne veux donc pas les stocker.

7 votes

Réponse : dict(list( df.groupby(['A'])['C'] ))

5 votes

Note : il est plus efficace (mais équivalent) d'utiliser dict(iter(g)) . (bien que get_group est le meilleur moyen / car il n'implique pas la création d'un dictionnaire / vous permet de rester dans pandas ! :D )

27voto

LegitMe Points 500

Plutôt que de

gb.get_group('foo')

Je préfère utiliser gb.groups

df.loc[gb.groups['foo']]

En effet, de cette manière, vous pouvez également choisir plusieurs colonnes, par exemple :

df.loc[gb.groups['foo'],('A','B')]

6 votes

Note : Vous pouvez sélectionner différentes colonnes en utilisant gb[["A", "B"]].get_group("foo") .

8voto

Surya Points 4152
gb = df.groupby(['A'])

gb_groups = grouped_df.groups

Si vous recherchez des objets groupby sélectifs, faites : gb_groups.keys(), et entrez la clé désirée dans la key_list suivante

gb_groups.keys()

key_list = [key1, key2, key3 and so on...]

for key, values in gb_groups.iteritems():
    if key in key_list:
        print df.ix[values], "\n"

6voto

meyerson Points 51

Je cherchais un moyen d'échantillonner quelques membres de l'objet GroupBy - j'ai dû répondre à la question affichée pour y parvenir.

créer un objet groupby basé sur some_key colonne

grouped = df.groupby('some_key')

choisir N cadres de données et récupérer leurs indices

sampled_df_i  = random.sample(grouped.indices, N)

saisir les groupes

df_list  = map(lambda df_i: grouped.get_group(df_i), sampled_df_i)

optionnellement - transformer le tout en un seul objet dataframe

sampled_df = pd.concat(df_list, axis=0, join='outer')

1 votes

Ça ne marche pas : sampled_df_i = random.sample(grouped.indicies, N)

0 votes

@irene - pouvez-vous fournir un lien vers un exemple plus long/plus de contexte ?

0 votes

Je reçois l'erreur suivante : AttributeError: 'DataFrameGroupBy' object has no attribute 'indicies'

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X