2013-02-21 20 views
16

Sto provando a capovolgere i metodi di gruppo di Pandas. Mi piacerebbe scrivere una funzione che faccia alcune funzioni di aggregazione e poi restituisca un DataFrame di Pandas. Ecco un esempio molto semplificato usando sum(). So che ci sono modi più facili per fare le somme semplici, nella vita reale la mia funzione è più complessa:ritorno del dataframe aggregato dal gruppo dei panda da

import pandas as pd 
df = pd.DataFrame({'col1': ['A', 'A', 'B', 'B'], 'col2':[1.0, 2, 3, 4]}) 

In [3]: df 
Out[3]: 
    col1 col2 
0 A  1 
1 A  2 
2 B  3 
3 B  4 

def func2(df): 
    dfout = pd.DataFrame({ 'col1' : df['col1'].unique() , 
          'someData': sum(df['col2']) }) 
    return dfout 

t = df.groupby('col1').apply(func2) 

In [6]: t 
Out[6]: 
     col1 someData 
col1     
A 0 A   3 
B 0 B   7 

non mi aspettavo di avere col1 a due volte e non mi aspettavo che cosa indice di mistero alla ricerca. Ho davvero pensato di ottenere col1 & someData.

Nella mia applicazione di vita reale sto raggruppando da più di una colonna e vorrei davvero recuperare un DataFrame e non un oggetto Serie.
Qualche idea per una soluzione o una spiegazione su cosa sta facendo Pandas nel mio esempio sopra?

----- ----- informazioni aggiunto

avrei dovuto iniziare con questo esempio, penso:

In [13]: import pandas as pd 

In [14]: df = pd.DataFrame({'col1':['A','A','A','B','B','B'], 'col2':['C','D','D','D','C','C'], 'col3':[.1,.2,.4,.6,.8,1]}) 

In [15]: df 
Out[15]: 
    col1 col2 col3 
0 A C 0.1 
1 A D 0.2 
2 A D 0.4 
3 B D 0.6 
4 B C 0.8 
5 B C 1.0 

In [16]: def func3(df): 
    ....:   dfout = sum(df['col3']**2) 
    ....:   return dfout 
    ....: 

In [17]: t = df.groupby(['col1', 'col2']).apply(func3) 

In [18]: t 
Out[18]: 
col1 col2 
A  C  0.01 
     D  0.20 
B  C  1.64 
     D  0.36 

Nell'illustrazione sopra il risultato della funzione apply() è una serie di panda. E manca le colonne groupby dal df.groupby. L'essenza di ciò con cui sto lottando è come faccio a creare una funzione che applico a un groupby che restituisce sia il risultato della funzione AND le colonne su cui è stato raggruppato?

----- ancora un altro aggiornamento ------

Sembra che se io poi faccio:

pd.DataFrame(t).reset_index() 

torno un dataframe, che è molto vicino a quello che stavo cercando

+1

btw, questo tutorial da uno dei programmatori panda ha aiutato a capire la meccanica GroupBy e di aggregazione di panda: https://www.youtube.com/watch?v=MxRMXhjXZos – Zelazny7

+0

Nell'esempio che hai aggiunti , qual è lo scopo del groupby (troverà solo i duplicati), puoi semplicemente fare una domanda a df stesso e aggiungerla come una colonna: 'df ['func3'] = df.applicare (riga lambda: riga ['col2'] ** 2, asse = 1) '. ? –

+0

I dati sono un po 'troppo semplici per l'esempio, temo. Aggiornerò l'esempio –

risposta

6

Il motivo per cui si visualizzano le colonne con 0s è perché l'output di .unique() è un array .

Il modo migliore per capire come il vostro si applicano è andare a lavorare è quello di ispezionare ogni gruppo di azione-saggio:

In [11] :g = df.groupby('col1') 

In [12]: g.get_group('A') 
Out[12]: 
    col1 col2 
0 A  1 
1 A  2 

In [13]: g.get_group('A')['col1'].unique() 
Out[13]: array([A], dtype=object) 

In [14]: sum(g.get_group('A')['col2']) 
Out[14]: 3.0 

La maggior parte del tempo si desidera che questo sia un valore aggregato .

L'uscita del grouped.apply avrà sempre le etichette di gruppo come un indice (i valori unici di 'col1'), quindi il vostro esempio la costruzione di col1 sembra un po 'ottusa per me.

Nota: per eseguire il pop 'col1' (l'indice) su una colonna, è possibile chiamare reset_index, quindi in questo caso.

In [15]: g.sum().reset_index() 
Out[15]: 
    col1 col2 
0 A  3 
1 B  7 
+0

Grazie per la spiegazione sull'array. Sto chiaramente portando il mio bagaglio R a Python. –

+0

per una funzione arbitraria che sto applicando, il groupby sembra eliminare le mie colonne di raggruppamento dal risultato e restituisce solo una serie di risposte. Utilizzare chiaramente il metodo sum() lo aggira, ma non è utile per le funzioni personalizzate che non sono implementate come metodi groupby. Ho aggiunto un esempio alla mia domanda per illustrare meglio. –

+0

@JDLong siete groupby su ogni colonna? (per me, questa sembra una cosa strana da fare, ma sono d'accordo che l'uscita è un po 'strana: non avendo il MultiIndex delle colonne): s –