Tengo un marco de datos de pandas que se ve así
ID country month revenue profit ebit 234 USA 201409 10 5 3 344 USA 201409 9 7 2 532 UK 201410 20 10 5 129 Canada 201411 15 10 5Quiero agrupar por identificación, país, mes y contar las identificaciones por mes y país y sumar los ingresos, ganancias, ebit. La salida para los datos anteriores sería:
country month revenue profit ebit count USA 201409 19 12 5 2 UK 201409 20 10 5 1 Canada 201411 15 10 5 1He probado diferentes variaciones de las funciones groupby, sum y count de pandas, pero no puedo descifrar cómo aplicar groupby sum y contar todos juntos para obtener el resultado que se muestra. Por favor, comparta cualquier idea que pueda tener. ¡Gracias!
Se puede hacer usando pivot_table esta manera:
>>> df1=pd.pivot_table(df, index=['country','month'],values=['revenue','profit','ebit'],aggfunc=np.sum) >>> df1 ebit profit revenue country month Canada 201411 5 10 15 UK 201410 5 10 20 USA 201409 5 12 19 >>> df2=pd.pivot_table(df, index=['country','month'], values='ID',aggfunc=len).rename('count') >>> df2 country month Canada 201411 1 UK 201410 1 USA 201409 2 >>> pd.concat([df1,df2],axis=1) ebit profit revenue count country month Canada 201411 5 10 15 1 UK 201410 5 10 20 1 USA 201409 5 12 19 2ACTUALIZAR
Se puede hacer en una sola línea usando pivot_table y proporcionando un dict de funciones para aplicar a cada columna en el argumento aggfunc :
pd.pivot_table( df, index=['country','month'], aggfunc={'revenue': np.sum, 'profit': np.sum, 'ebit': np.sum, 'ID': len} ).rename(columns={'ID': 'count'}) count ebit profit revenue country month Canada 201411 1 5 10 15 UK 201410 1 5 10 20 USA 201409 2 5 12 19Puede agrupar y luego asignar los recuentos de cada país a una nueva columna.
g = df.groupby(['country', 'month'])['revenue', 'profit', 'ebit'].sum().reset_index() g['count'] = g['country'].map(df['country'].value_counts()) g Out[3]: country month revenue profit ebit count 0 Canada 201411 15 10 5 1 1 UK 201410 20 10 5 1 2 USA 201409 19 12 5 2Editar
Para obtener los recuentos por país y mes, puede hacer otro grupo y luego unir los dos marcos de datos.
g = df.groupby(['country', 'month'])['revenue', 'profit', 'ebit'].sum() j = df.groupby(['country', 'month']).size().to_frame('count') pd.merge(g, j, left_index=True, right_index=True).reset_index() Out[6]: country month revenue profit ebit count 0 Canada 201411 15 10 5 1 1 UK 201410 20 10 5 1 2 UK 201411 10 5 2 1 3 USA 201409 19 12 5 2Agregué otro registro para el Reino Unido con una fecha diferente: observe cómo ahora hay dos entradas del Reino Unido en el DataFrame fusionado, con los recuentos apropiados.
La siguiente solución parece la más sencilla.
Agrupar por país y mes:
grouped_df = df.groupby(['country', 'month'])Aplique la suma a las columnas de interés (ingresos, ganancias, ebit):
final = grouped_df[['revenue', 'profit', 'ebit']].agg('sum')Asigne el tamaño de grouped_df a una nueva columna en 'final':
final['count'] = grouped_df.size() print(final) Out[256]: revenue profit ebit count country month Canada 201411 15 10 5 1 UK 201410 20 10 5 1 USA 201409 19 12 5 2¡Todo listo!