Como somar valores agrupados por duas colunas nos pandas

21

Eu tenho um DataFrame do Pandas assim:

df = pd.DataFrame({
    'Date': ['2017-1-1', '2017-1-1', '2017-1-2', '2017-1-2', '2017-1-3'],
    'Groups': ['one', 'one', 'one', 'two', 'two'],
    'data': range(1, 6)})

    Date      Groups     data  
0  2017-1-1    one       1
1  2017-1-1    one       2
2  2017-1-2    one       3
3  2017-1-2    two       4
4  2017-1-3    two       5

Como posso gerar um novo DataFrame como este:

    Date       one     two 
0  2017-1-1    3        0
1  2017-1-2    3        4
2  2017-1-3    0        5
Kevin
fonte

Respostas:

16

pivot_table foi feito para isso:

df.pivot_table(index='Date',columns='Groups',aggfunc=sum)

resulta em

         data
Groups    one  two
Date
2017-1-1  3.0  NaN
2017-1-2  3.0  4.0
2017-1-3  NaN  5.0

Pessoalmente, acho essa abordagem muito mais fácil de entender e certamente mais pitônica do que uma operação de grupo complicada. Então, se você deseja que o formato seja especificado, basta organizá-lo:

df.fillna(0,inplace=True)
df.columns = df.columns.droplevel()
df.columns.name = None
df.reset_index(inplace=True)

o que te dá

       Date  one  two
0  2017-1-1  3.0  0.0
1  2017-1-2  3.0  4.0
2  2017-1-3  0.0  5.0
Josh D.
fonte
1
Agradável! Essa deve ser a resposta aceita.
tuomastik
@ Josh D. Isso é legal e direto! Concordo que é preciso algum poder cerebral para descobrir como o grupo trabalha. Obrigado!
21717 Kevin
8

Pandas magia negra:

df = df.groupby(['Date', 'Groups']).sum().sum(
    level=['Date', 'Groups']).unstack('Groups').fillna(0).reset_index()

# Fix the column names
df.columns = ['Date', 'one', 'two']

Resultante df:

       Date  one  two
0  2017-1-1  3.0  0.0
1  2017-1-2  3.0  4.0
2  2017-1-3  0.0  5.0
tuomastik
fonte
Piedosos! A magia negra é tão poderosa! Muito obrigado!
Kevin
De nada! Veja a resposta atualizada; Simplifiquei a expressão e adicionei uma correção para que os nomes das colunas fossem exatamente conforme solicitados.
tuomastik
Eu acho que sua versão anterior tem sua vantagem, pois pode ser aplicada a outros conjuntos de dados mais complicados. Copiei aqui: df.groupby (['Date', 'Groups', 'data']) ['data']. Sum (). Sum (level = ['Date', 'Groups']). Unstack ( 'Grupos'). Fillna (0)
Kevin
@ Kevin Se esta ou qualquer resposta futura resolver seu problema, aceite a resposta.
tuomastik