Pandy grupowane i sumowane

205

Używam tej ramki danych:

Fruit   Date      Name  Number
Apples  10/6/2016 Bob    7
Apples  10/6/2016 Bob    8
Apples  10/6/2016 Mike   9
Apples  10/7/2016 Steve 10
Apples  10/7/2016 Bob    1
Oranges 10/7/2016 Bob    2
Oranges 10/6/2016 Tom   15
Oranges 10/6/2016 Mike  57
Oranges 10/6/2016 Bob   65
Oranges 10/7/2016 Tony   1
Grapes  10/7/2016 Bob    1
Grapes  10/7/2016 Tom   87
Grapes  10/7/2016 Bob   22
Grapes  10/7/2016 Bob   12
Grapes  10/7/2016 Tony  15

Chcę to zagregować według nazwy, a następnie według owoców, aby uzyskać całkowitą liczbę owoców według nazwy.

Bob,Apples,16 ( for example )

Próbowałem pogrupować według nazw i owoców, ale jak uzyskać całkowitą liczbę owoców.

Trying_hard
źródło

Odpowiedzi:

209

Użyj GroupBy.sum:

df.groupby(['Fruit','Name']).sum()

Out[31]: 
               Number
Fruit   Name         
Apples  Bob        16
        Mike        9
        Steve      10
Grapes  Bob        35
        Tom        87
        Tony       15
Oranges Bob        67
        Mike       57
        Tom        15
        Tony        1
Steven G.
źródło
94
Skąd pandy mogą wiedzieć, że chcę podsumować nazwaną kolumnę Number?
Kingname
12
@Kingname to ostatnia kolumna, która została, jeśli wyjmiesz NAZWĘ i OWOCE. jeśli dodasz 2 kolumny, suma obu kolumn
Steven G.
9
Jak określić, która kolumna ma zostać zsumowana?
tgdn
34
@tgdn df.groupby (['Name', 'Fruit']) ['Number']. sum ()
Steven G
2
@StevenG Aby uzyskać odpowiedź podsumowującą określoną kolumnę, dane wyjściowe są wyświetlane jako seria Pandas zamiast Dataframe. Z komentarza Jakuba Kukula (w poniższej odpowiedzi) możemy użyć podwójnych nawiasów kwadratowych wokół „Liczby”, aby uzyskać ramkę danych.
skdhfgeq2134
178

Możesz także skorzystać z funkcji agg,

df.groupby(['Name', 'Fruit'])['Number'].agg('sum')
Saurabh
źródło
1
Różni się to od przyjętej odpowiedzi tym, że zwraca a, Seriespodczas gdy druga zwraca GroupByobiekt.
Gaurang Tandon
11
@GaurangTandon, aby DataFramezamiast tego uzyskać obiekt (jak w zaakceptowanej odpowiedzi), użyj podwójnych nawiasów kwadratowych wokół 'Number', tj .:df.groupby(['Name', 'Fruit'])[['Number']].agg('sum')
Jakub Kukul
1
Bardzo pomocny w usuwaniu źle zakodowanego raportu zapytania.
avirr
92

Jeśli chcesz zachować oryginalne kolumny Fruiti Name, użyj reset_index(). Inaczej Fruiti Namestaną się częścią indeksu.

df.groupby(['Fruit','Name'])['Number'].sum().reset_index()

Fruit   Name       Number
Apples  Bob        16
Apples  Mike        9
Apples  Steve      10
Grapes  Bob        35
Grapes  Tom        87
Grapes  Tony       15
Oranges Bob        67
Oranges Mike       57
Oranges Tom        15
Oranges Tony        1

Jak widać w innych odpowiedziach:

df.groupby(['Fruit','Name'])['Number'].sum()

               Number
Fruit   Name         
Apples  Bob        16
        Mike        9
        Steve      10
Grapes  Bob        35
        Tom        87
        Tony       15
Oranges Bob        67
        Mike       57
        Tom        15
        Tony        1
Gazala Muhamed
źródło
43

Obie pozostałe odpowiedzi spełniają Twoje oczekiwania.

Możesz użyć tej pivotfunkcji, aby uporządkować dane w ładnej tabeli

df.groupby(['Fruit','Name'],as_index = False).sum().pivot('Fruit','Name').fillna(0)



Name    Bob     Mike    Steve   Tom    Tony
Fruit                   
Apples  16.0    9.0     10.0    0.0     0.0
Grapes  35.0    0.0     0.0     87.0    15.0
Oranges 67.0    57.0    0.0     15.0    1.0
Demetri Pananos
źródło
19
df.groupby(['Fruit','Name'])['Number'].sum()

Możesz wybrać różne kolumny, aby zsumować liczby.

jared
źródło
7

Możesz ustawić groupbykolumnę, aby index następnie używać sumzlevel

df.set_index(['Fruit','Name']).sum(level=[0,1])
Out[175]: 
               Number
Fruit   Name         
Apples  Bob        16
        Mike        9
        Steve      10
Oranges Bob        67
        Tom        15
        Mike       57
        Tony        1
Grapes  Bob        35
        Tom        87
        Tony       15
YOBEN_S
źródło
3

Odmiana funkcji .agg (); zapewnia możliwość (1) zachowania typu DataFrame, (2) zastosowania średnich, zliczeń, sumowań itp. oraz (3) umożliwia grupowanie według wielu kolumn przy zachowaniu czytelności.

df.groupby(['att1', 'att2']).agg({'att1': "count", 'att3': "sum",'att4': 'mean'})

używając twoich wartości ...

df.groupby(['Name', 'Fruit']).agg({'Number': "sum"})
xxyjoel
źródło