I panda sommano per groupby, ma escludono alcune colonne


89

Qual è il modo migliore per eseguire un groupby su un dataframe Pandas, ma escludere alcune colonne da quel groupby? ad esempio, ho il seguente dataframe:

Code   Country      Item_Code   Item    Ele_Code    Unit    Y1961    Y1962   Y1963
2      Afghanistan  15          Wheat   5312        Ha      10       20      30
2      Afghanistan  25          Maize   5312        Ha      10       20      30
4      Angola       15          Wheat   7312        Ha      30       40      50
4      Angola       25          Maize   7312        Ha      30       40      50

Voglio raggruppare la colonna Paese e Item_Code e calcolare solo la somma delle righe che rientrano nelle colonne Y1961, Y1962 e Y1963. Il dataframe risultante dovrebbe essere simile a questo:

Code   Country      Item_Code   Item    Ele_Code    Unit    Y1961    Y1962   Y1963
2      Afghanistan  15          C3      5312        Ha      20       40       60
4      Angola       25          C4      7312        Ha      60       80      100

In questo momento lo sto facendo:

df.groupby('Country').sum()

Tuttavia, questo somma anche i valori nella colonna Item_Code. C'è un modo per specificare quali colonne includere sum()nell'operazione e quali escludere?

Risposte:


120

Puoi selezionare le colonne di un gruppo per:

In [11]: df.groupby(['Country', 'Item_Code'])[["Y1961", "Y1962", "Y1963"]].sum()
Out[11]:
                       Y1961  Y1962  Y1963
Country     Item_Code
Afghanistan 15            10     20     30
            25            10     20     30
Angola      15            30     40     50
            25            30     40     50

Nota che l'elenco passato deve essere un sottoinsieme delle colonne altrimenti vedrai un KeyError.


1
Come includere il conteggio dei record per ogni paese e codice articolo come un'altra colonna?
Sushant Kulkarni

È possibile creare una colonna fittizia prima di raggruppare per che contiene solo 1. quindi sum sommerà quelli creando un conteggio.
Matt W.

Se vuoi solo escludere una o due colonne, ottieni tutti i nomi delle colonne come in, listColumns = list(df.columns)quindi rimuovi le colonne che non vuoi listColumns.remove('Y1964')e infine fai la tua somma:df.groupby(['Country', 'Item_Code'])[listColumns].sum()
Roberto Stelling

Molte grazie. Posso far lavorare il gruppo, ma non la parte di selezione. L'elenco delle colonne che ho inserito è tra i dataframe, ma continua ad aumentare ValueError:cannot reindex from a duplicate axis
Bowen Liu

@BowenLiu se hai più colonne con lo stesso nome mostrerà questo errore. In questo caso dovrai usare iloc to o loc per ottenere le colonne che desideri, penso che dovrai farlo prima del groupby.
Andy Hayden

40

La aggfunzione lo farà per te. Passa le colonne e funziona come un comando con colonna, output:

df.groupby(['Country', 'Item_Code']).agg({'Y1961': np.sum, 'Y1962': [np.sum, np.mean]})  # Added example for two output columns from a single input column

Verrà visualizzato solo il gruppo per colonne e le colonne aggregate specificate. In questo esempio ho incluso due funzioni agg applicate a "Y1962".

Per ottenere esattamente ciò che speravi di vedere, includi le altre colonne nel gruppo per e applica le somme alle variabili Y nel frame:

df.groupby(['Code', 'Country', 'Item_Code', 'Item', 'Ele_Code', 'Unit']).agg({'Y1961': np.sum, 'Y1962': np.sum, 'Y1963': np.sum})

1
grazie, può essere generalizzato? Ho molte colonne nella forma Y1961 ... quindi creo una lista come questa: yrs = ['Y' + str (x) for x in range (1961, 2010 + 1, 1)]. La tua soluzione può utilizzare "anni" all'interno di agg?
user308827

Mi piace molto questa idea. Il trucco è costruire questo dict con il valore che è la funzione numpy sum. Al contrario, però, se tutto ciò che vuoi fare è sommare tutte le colonne rimanenti, la tua soluzione originale funzionerebbe se tutte le colonne group by sono incluse nell'istruzione group by.
leroyJr

11

Se stai cercando un modo più generalizzato per applicare a molte colonne, quello che puoi fare è creare un elenco di nomi di colonne e passarlo come indice del dataframe raggruppato. Nel tuo caso, ad esempio:

columns = ['Y'+str(i) for year in range(1967, 2011)]

df.groupby('Country')[columns].agg('sum')
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.