Tengo un marco de datos df :
2019 2020 2021 2022 A 1 10 15 15 31 2 5 4 7 9 3 0.3 0.4 0.4 0.7 4 500 600 70 90 B 1 10 15 15 31 2 5 4 7 9 3 0.3 0.4 0.4 0.7 4 500 600 70 90 C 1 10 15 15 31 2 5 4 7 9 3 0.3 0.4 0.4 0.7 4 500 600 70 90 D 1 10 15 15 31 2 5 4 7 9 3 0.3 0.4 0.4 0.7 4 500 600 70 90 Estoy tratando de agrupar por el índice de nivel 1, 1, 2, 3, 4 y asignar diferentes funciones de agregación para esos índices 1, 2, 3, 4 para que 1 se agregue por sum , 2 por mean , y así sucesivamente. Para que el resultado final se vea así:
2019 2020 2021 2022 1 40 ... ... # sum 2 5 ... ... # mean 3 0.3 ... ... # mean 4 2000 ... ... # sumLo intenté:
df.groupby(level = 1).agg({'1':'sum', '2':'mean', '3':'sum', '4':'mean'}) Pero entiendo que ninguno de 1, 2, 3, 4 está en columnas que no lo están, por lo que no estoy seguro de cómo debo proceder con este problema.
Puede usar apply con una función personalizada de la siguiente manera:
import numpy as np aggs = {1: np.sum, 2: np.mean, 3: np.mean, 4: np.sum} def f(x): func = aggs.get(x.name, np.sum) return func(x) df.groupby(level=1).apply(f) El código anterior usa la suma de forma predeterminada, por lo que 1 y 4 podrían eliminarse de aggs sin resultados diferentes. De esta manera, solo se deben especificar los grupos que deben manejarse de manera diferente al resto.
Resultado:
2019 2020 2021 2022 1 40.0 60.0 60.0 124.0 2 5.0 4.0 7.0 9.0 3 0.3 0.4 0.4 0.7 4 2000.0 2400.0 280.0 360.0En caso de que quisieras evitar bucles for. Cortar y agrupar por índice y agregar condicionalmente.
df1 = ( df.groupby([df.index.get_level_values(level=1)]).agg( lambda x: x.sum() if x.index.get_level_values(level=1).isin([1,4]).any() else x.mean()) ) df1 2019 2020 2021 2022 1 40.0 60.0 60.0 124.0 2 5.0 4.0 7.0 9.0 3 0.3 0.4 0.4 0.7 4 2000.0 2400.0 280.0 360.0