web-dev-qa-db-fra.com

Comment accéder à pandas _ groupby dataframe by key

Comment accéder à la frameframe groupby correspondante dans un objet groupby à l'aide de 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 parcourir 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

J'aimerais pouvoir faire quelque chose comme

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 je fais ça (enfin, en fait je dois faire gb[('foo',)]), je reçois cette chose bizarre pandas.core.groupby.DataFrameGroupBy qui ne semble pas avoir de méthode correspondant au DataFrame que je veux.

Le mieux que 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 un peu vilain, vu la façon dont Nice pandas est habituellement à ces choses.
Quelle est la manière inhérente de faire cela?

123
beardc

Vous pouvez utiliser la méthode get_group :

_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
_

Remarque: cela ne nécessite pas de créer un dictionnaire intermédiaire/une copie de chaque sous-trame de données pour chaque groupe. La mémoire sera donc beaucoup plus efficace que la création du dictionnaire naïf avec dict(iter(gb)). En effet, il utilise des structures de données déjà disponibles dans l'objet groupby.


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

_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
_
161
Andy Hayden

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 les étiquettes de votre groupe et dont les valeurs sont DataFrames, c.-à-d.

groups['foo']

donnera ce que vous cherchez:

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

Plutôt que

gb.get_group('foo')

Je préfère utiliser gb.groups

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

Parce que de cette façon, vous pouvez également choisir plusieurs colonnes. par exemple:

df.loc[gb.groups['foo'],('A','B')]
17
LegitMe
gb = df.groupby(['A'])

gb_groups = grouped_df.groups

Si vous recherchez des objets groupby sélective, faites: gb_groups.keys () et entrez la clé souhaitée dans la liste de clés 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"
5
Surya

Je cherchais un moyen d'échantillonner quelques membres du groupe. Par obj - je devais répondre à la question affichée pour que cela soit fait.

créer un objet groupby

grouped = df.groupby('some_key')

sélectionnez N dataframes et récupérez leurs indicateurs

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

attraper les groupes

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

éventuellement - reconvertissez tout cela en un seul objet dataframe

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