Cómo sumar valores agrupados por dos columnas en pandas


21

Tengo un Pandas DataFrame como este:

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

¿Cómo puedo generar un nuevo DataFrame como este:

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

Respuestas:


16

pivot_table fue hecho para esto:

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

resultados en

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

Personalmente, encuentro este enfoque mucho más fácil de entender, y ciertamente más pitónico que una operación grupal enrevesada. Luego, si desea que se especifique el formato, puede ordenarlo:

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

que te da

       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

1
¡Agradable! Esta debería ser la respuesta aceptada.
tuomastik

@Josh D. ¡Esto es genial y sencillo! Estoy de acuerdo en que se necesita algo de poder mental para descubrir cómo funciona groupby. ¡Gracias!
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

¡Santo! ¡La magia negra es tan poderosa! ¡Muchas gracias!
Kevin

¡De nada! Ver la respuesta actualizada; Simplifiqué la expresión y agregué una solución para que los nombres de las columnas sean exactamente como se solicitó.
tuomastik

Creo que su versión anterior tiene su ventaja, ya que se puede aplicar a otros conjuntos de datos más complicados. Lo copié aquí: df.groupby (['Fecha', 'Grupos', 'datos']) ['datos']. Sum (). Sum (nivel = ['Fecha', 'Grupos']). Unstack ( 'Grupos'). Fillna (0)
Kevin

@Kevin Si esta o cualquier respuesta futura resolvió su problema, acepte la respuesta.
tuomastik
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.