color y
0 azul -4.333333
1 negro 2.000000
2 rojo 3.500000
Es desaconsejable porque: * Tendrás que renombrar manualmente los nombres de las columnas, que mantienen el nombre de la columna original y no de la función aplicada. * No puedes aplicar el método a más de una función y columna de manera simultánea * No puedes usar cualquier función, solo algunas conocidas.
Otro método que es posible usar, pero no conviene tanto es usar agg:
df_g = df.groupby("color").agg( {"x": [lambda _: _.mean()], # aplicado a y"y": [lambda _: _.nunique(), lambda _: _.mean()], # aplicado a z })print(df_g)
x y
<lambda> <lambda_0> <lambda_1>
color
azul -2.666667 2 -4.333333
negro 2.000000 3 2.000000
rojo -3.500000 2 3.500000
Es desaconsejable porque: * Genera 2 niveles de columnas: es dificil de “aplanar” * Hace incluso más difícil renombrar las columnas. Pero al menos es mejor que el método anterior porque puedes usar funciones genéricas.
Método sugerido
El método que aconsejo es con agg pero con definición explícita de los nombres de las columnas.
Después del groupby, aplicas el método agg pasándole inventando un nombre del parámetro deseado y dándole como valor una tupla (columna, función).
¡Las columnas generadas obtienen inmediatamente el nombre deseado!
El groupby puede recibir una lista de columnas en caso de necesitar un nivel de agregación más detallado.
Notar que las columnas a generar se pasan como parámetros de la función (promedio_y) y no strings ("promedio_y")!!!
Multicolumna
Una mejora interesante es usar lo anterior para trabajar con múltiples columnas al mismo tiempo. Veamos un ejemplo concreto: calculando distintas métricas (distancias) respecto al origen (0,0).
Para poder aplicar el truco anterior, necesitamos “empaquetar las columnas” en una variable
Y ahora podemos aplicar distintas funciones, aunque en general será mejor definirlas como funciones (más que lambda-funciones) para expresar mejor las relaciones a usar entre los elementos: