¿Agrupar el marco de datos y obtener la suma Y el recuento?


82

Tengo un marco de datos que se parece a esto:

              Company Name              Organisation Name  Amount
10118  Vifor Pharma UK Ltd  Welsh Assoc for Gastro & Endo 2700.00
10119  Vifor Pharma UK Ltd    Welsh IBD Specialist Group,  169.00
10120  Vifor Pharma UK Ltd             West Midlands AHSN 1200.00
10121  Vifor Pharma UK Ltd           Whittington Hospital   63.00
10122  Vifor Pharma UK Ltd                 Ysbyty Gwynedd   75.93

¿Cómo sumo Amounty cuento Organisation Namepara obtener un nuevo marco de datos que se ve así?

              Company Name             Organisation Count   Amount
10118  Vifor Pharma UK Ltd                              5 11000.00

Sé sumar o contar:

df.groupby('Company Name').sum()
df.groupby('Company Name').count()

¡Pero no cómo hacer ambas cosas!

Respuestas:


147

prueba esto:

In [110]: (df.groupby('Company Name')
   .....:    .agg({'Organisation Name':'count', 'Amount': 'sum'})
   .....:    .reset_index()
   .....:    .rename(columns={'Organisation Name':'Organisation Count'})
   .....: )
Out[110]:
          Company Name   Amount  Organisation Count
0  Vifor Pharma UK Ltd  4207.93                   5

o si no desea restablecer el índice:

df.groupby('Company Name')['Amount'].agg(['sum','count'])

o

df.groupby('Company Name').agg({'Amount': ['sum','count']})

Manifestación:

In [98]: df.groupby('Company Name')['Amount'].agg(['sum','count'])
Out[98]:
                         sum  count
Company Name
Vifor Pharma UK Ltd  4207.93      5

In [99]: df.groupby('Company Name').agg({'Amount': ['sum','count']})
Out[99]:
                      Amount
                         sum count
Company Name
Vifor Pharma UK Ltd  4207.93     5

2
@MaxU hay una manera de aplicar la suma y el recuento a diferentes pero múltiples coulmns. Cuando trato de dar las columnas como una lista como esta: agg ({['hotel_name', 'hotel_country']: 'cuenta', ['costo', 'ingresos', 'clics']: 'suma'}) da Error "TypeError: unhashable type: 'list'"
CanCeylan

@CanCeylan no sé si es posible hacerlo en una cláusula groupby, pero puede lograrlo agregando una columna de conteo ficticia al marco de datos de antemano y luego hacer una suma groupby:df['count'] = 1
Karl Anka

1
Finalmente, 2 horas de búsqueda de cómo hacer esto ... solo la tercera opción: df.groupby ('Nombre de la empresa'). Agg ({'Amount': ['sum', 'count']}) funcionó para mí .
charo

Hola, gracias por esa gran solución. En mi caso particular, estoy usando su solución en dos columnas diferentes para obtener la suma y contar el número de filas. Desafortunadamente, obtengo el número de filas dos veces (ofc. Porque cuenta para ambas columnas). ¿Hay alguna forma de eliminar uno de los .counts para que mi mesa se vea limpia? df.groupby(df['L2 Name'])[["Amount arrear","VSU"]].agg(['sum','count'])
MLAlex

Hola gracias por tu gran respuesta. ¿Sabes cómo interpretar las nuevas columnas que se crean y cómo aplanarlas de una forma más tradicional?
Solal

20

En caso de que se pregunte cómo cambiar el nombre de las columnas durante la agregación, aquí se explica cómo

pandas> = 0.25: Agregación con nombre

df.groupby('Company Name')['Amount'].agg(MySum='sum', MyCount='count')

O,

df.groupby('Company Name').agg(MySum=('Amount', 'sum'), MyCount=('Amount', 'count'))

                       MySum  MyCount
Company Name                       
Vifor Pharma UK Ltd  4207.93        5

Esta debería ser la respuesta exceptuada, ¿hay alguna manera de actualizar las preguntas / respuestas antiguas con la nueva forma mejor de hacer las cosas? La respuesta exceptuada no es incorrecta, simplemente ya no es la mejor manera.
JSharm

@JSharm obviamente no puede cambiar la opinión del OP, pero ciertamente puede votar las publicaciones que siente que merecen estar en la parte superior. Si suficientes personas piensan y actúan de la misma manera que usted, llegaremos allí algún día;) PD: no echar sombra a la respuesta aceptada, sigo pensando que es la mejor respuesta para esta pregunta siempre que los pandas continúen apoyando la sintaxis, que estoy razonablemente seguro de que será por un buen tiempo todavía.
cs95

4

Si tiene muchas columnas y solo una es diferente, puede hacer:

In[1]: grouper = df.groupby('Company Name')
In[2]: res = grouper.count()
In[3]: res['Amount'] = grouper.Amount.sum()
In[4]: res
Out[4]:
                      Organisation Name   Amount
Company Name                                   
Vifor Pharma UK Ltd                  5  4207.93

Tenga en cuenta que puede cambiar el nombre de la columna Nombre de la organización como desee.


1
df.groupby('Company Name').agg({'Organisation name':'count','Amount':'sum'})\
    .apply(lambda x: x.sort_values(['count','sum'], ascending=False))
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.