Pandas agrupados e soma

206

Estou usando esse quadro de dados:

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

Quero agregar isso por nome e depois por fruta para obter um número total de frutas por nome.

Bob,Apples,16 ( for example )

Tentei agrupar por nome e fruta, mas como obtenho o número total de frutas.

Trying_hard
fonte

Respostas:

210

Use 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
fonte
95
Como os pandas podem saber que eu quero somar a coluna chamada Number?
Kingname 23/10
12
@Kingname é a última coluna restante, se você remover NAME e FRUIT. se você adicionar duas colunas restantes, somará as duas colunas
Steven G
9
Como especificar qual coluna somar?
tgdn
35
@tgdn df.groupby (['Name', 'Fruit']) ['Number']. sum ()
Steven G
2
@StevenG Para a resposta fornecida para resumir uma coluna específica, a saída sai como uma série do Pandas, em vez do Dataframe. A partir do comentário de Jakub Kukul (na resposta abaixo), podemos usar colchetes duplos em torno de 'Number' para obter um Dataframe.
skdhfgeq2134 16/01
179

Além disso, você pode usar a função agg,

df.groupby(['Name', 'Fruit'])['Number'].agg('sum')
Saurabh
fonte
1
Isso difere da resposta aceita, pois retorna a Seriesenquanto o outro retorna um GroupByobjeto.
Gaurang Tandon
11
@GaurangTandon para obter o DataFrameobjeto (como na resposta aceita), use colchetes duplos ao redor 'Number', ou seja:df.groupby(['Name', 'Fruit'])[['Number']].agg('sum')
Jakub Kukul
1
Muito útil para limpar o relatório de consulta mal codificado.
Avirr 9/10/19
93

Se você deseja manter as colunas originais Fruite Name, use reset_index(). Caso contrário, Fruite Namese tornará parte do índice.

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

Como visto nas outras respostas:

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
fonte
43

As duas respostas realizam o que você deseja.

Você pode usar a pivotfuncionalidade para organizar os dados em uma boa tabela

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
fonte
19
df.groupby(['Fruit','Name'])['Number'].sum()

Você pode selecionar colunas diferentes para somar números.

jared
fonte
7

Você pode definir a groupbycoluna para index usar sumcomlevel

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
fonte
3

Uma variação na função .agg (); fornece a capacidade de (1) persistir o tipo DataFrame, (2) aplicar médias, contagens, somatórios etc. e (3) permite agrupar em várias colunas enquanto mantém a legibilidade.

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

usando seus valores ...

df.groupby(['Name', 'Fruit']).agg({'Number': "sum"})
xxyjoel
fonte