Come accedere ai panda groupby dataframe per chiave


154

Come posso accedere al frame di dati groupby corrispondente in un oggetto groupby con la chiave?

Con il seguente gruppo:

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'])

Posso iterare attraverso di esso per ottenere le chiavi e i gruppi:

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

Vorrei poter accedere a un gruppo con la sua chiave:

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

Ma quando provo a farlo con gb[('foo',)]questo strano pandas.core.groupby.DataFrameGroupByoggetto che sembra non avere alcun metodo corrispondente al DataFrame che desidero.

Il meglio che mi viene in mente è:

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  

ma questo è un po 'brutto, considerando quanto sono belli i panda di solito in queste cose.
Qual è il modo integrato per farlo?

Risposte:


192

Puoi usare il get_groupmetodo:

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

Nota: ciò non richiede la creazione di un dizionario intermedio / copia di ogni subdataframe per ogni gruppo, quindi sarà molto più efficiente in termini di memoria rispetto alla creazione del dizionario ingenuo con dict(iter(gb)). Questo perché utilizza strutture di dati già disponibili nell'oggetto groupby.


È possibile selezionare diverse colonne utilizzando l'affettamento 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

72

Wes McKinney (autore dei panda) in Python for Data Analysis fornisce la seguente ricetta:

groups = dict(list(gb))

che restituisce un dizionario le cui chiavi sono le etichette del gruppo e i cui valori sono DataFrames, ad es

groups['foo']

produrrà ciò che stai cercando:

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

1
Grazie, è molto utile. Come posso modificare il codice per rendere groups = dict(list(gb))unica colonna di archivio C? Diciamo che non sono interessato alle altre colonne e quindi non voglio memorizzarle.
Zhubarb,

5
Risposta:dict(list( df.groupby(['A'])['C'] ))
Zhubarb,

4
Nota: è più efficiente (ma equivalente) da usare dict(iter(g)). (Anche se get_groupè il modo migliore / poiché non implica la creazione di un dizionario / ti tiene in panda!: D)
Andy Hayden

Non sono stato in grado di utilizzare i gruppi (dict (list (gb)) ma è possibile creare un dizionario nel modo seguente: gb_dict = {str(indx): str(val) for indx in gb.indx for val in gb.some_key}e quindi recuperare il valore tramitegb_dict[some_key]
user2476665

Basta usare get_group(), questa ricetta non è stata necessaria per anni.
smci,

20

Piuttosto che

gb.get_group('foo')

Preferisco usare gb.groups

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

Perché in questo modo puoi scegliere anche più colonne. per esempio:

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

4
Nota: è possibile selezionare diverse colonne usando gb[["A", "B"]].get_group("foo").
Andy Hayden,

6
gb = df.groupby(['A'])

gb_groups = grouped_df.groups

Se stai cercando oggetti groupby selettivi, allora: gb_groups.keys (), e inserisci la chiave desiderata nel seguente elenco di chiavi.

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"

1

Stavo cercando un modo per assaggiare alcuni membri del GroupBy obj - ho dovuto rispondere alla domanda postata per farlo.

creare un oggetto groupby

grouped = df.groupby('some_key')

scegli N frame di dati e prendi le loro indicazioni

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

prendi i gruppi

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

facoltativamente: trasforma tutto in un singolo oggetto dataframe

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

1
Questo non funziona:sampled_df_i = random.sample(grouped.indicies, N)
irene il

@irene - puoi fornire un link a un esempio più lungo / più contesto?
Meyerson,

Ottengo il seguente errore:AttributeError: 'DataFrameGroupBy' object has no attribute 'indicies'
irene
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.