Función df.groupby() de Pandas

Funciones comunes de Pandas


groupby()Es una de las funciones de agrupación más potentes de Pandas; te permite dividir los datos en diferentes grupos según los valores de una o más columnas y luego realizar diversas operaciones en cada grupo.

En términos simples,groupby()implementa el flujo de trabajo"Dividir-Aplicar-Combinar"(Split-Apply-Combine): primero divide los datos según una condición, aplica la función correspondiente a cada grupo y finalmente combina los resultados.

Esto es muy común en el análisis de datos, por ejemplo, calcular el salario promedio de los empleados por departamento, las ventas por mes, el número de usuarios por región, etc.


Sintaxis básica y parámetros

groupby()Es una función miembro de DataFrame, se invoca mediante el operador punto.Al llamarla, se devuelve un objetoGroupByobjeto, que por sí mismo no muestra el resultado directamente; debe usarse junto con funciones de agregación.

Formato de sintaxis

DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, dropna=True)

Descripción de parámetros

Parámetro Tipo Descripción Valor por defecto
by str, list o dict Nombre de la columna o lista de nombres de columnas para agrupar. Si es un diccionario o una función, agrupa según su resultado. None
axis int Eje de agrupación: 0 indica por filas (predeterminado), 1 indica por columnas. 0
level int o str Si es un MultiIndex, agrupa por el nivel especificado. None
as_index bool Si es True, las columnas de agrupación se usan como índice del resultado; si es False, las columnas de agrupación se conservan como columnas normales. True
sort bool Si ordena las etiquetas de grupo. Establecerlo en False puede mejorar el rendimiento. True
group_keys bool Al llamar aapply(), indica si se agregan las claves de agrupación como índice en el resultado. True
observed bool Si es True, solo se muestran los valores realmente observados de las variables categóricas, no todos los valores posibles. False
dropna bool Si es True, los grupos que contengan valores NA/null se descartan. True

Valor de retorno

  • Tipo de retorno:DataFrameGroupByoSeriesGroupByObjeto
  • Descripción: Se devuelve un objeto de agrupación, no el resultado final. Posteriormente se deben llamar funciones de agregación (comosum()、mean()、count(), etc.) para obtener resultados de cálculo concretos.

Ejemplos

Vamos a dominar completamente el uso degroupby()mediante una serie de ejemplos de simples a complejos.

Ejemplo 1: Agrupar por una sola columna

El uso más básico es agrupar según los valores de una columna. Supongamos que tenemos una tabla de datos de ventas y necesitamos calcular las ventas totales por región.

Ejemplo

import pandas as pd

# Crear un DataFrame simple de datos de ventas
# Simular una tabla que contiene región, producto y ventas
data = {
    'Región': ['Norte de China', 'Este de China', 'Sur de China', 'Norte de China', 'Este de China', 'Sur de China', 'Norte de China', 'Este de China'],
    'Producto': ['A', 'B', 'C', 'B', 'A', 'C', 'A', 'B'],
    'Ventas': [1000, 2000, 1500, 1800, 2200, 1600, 1200, 2100]
}

# Crear el DataFrame
df = pd.DataFrame(data)

print("Datos originales:")
print(df)
print()

# Agrupar por la columna "Región" y calcular las ventas totales de cada región
# as_index=True indica que la región se devuelve como índice
grouped = df.groupby('Región', as_index=True)['Ventas'].sum()

print("Ventas totales después de agrupar por región:")
print(grouped)
print()

# Con as_index=False, la columna de agrupación se conserva como columna normal
grouped_df = df.groupby('Región', as_index=False)['Ventas'].sum()

print("Resultado con as_index=False:")
print(grouped_df)

Resultado esperado:

原始数据:
  地区  产品   销售额
0  华东   B   2000
1  华南   C   1500
2  华北   A   1000
3  华东   B   1800
4  华南   C   2200
5  华北   A   1600
6  华东   A   1200
7  华南   B   2100

按地区分组后的总销售额:
地区
华东    7100
华南    7300
华北    3600
dtype: int64

as_index=False 时的结果:
   地区    销售额
0  华东    7100
1  华南    7300
2  华北    3600

Análisis del código:

  1. df.groupby('地区')Divide los datos en tres grupos según los valores de la columna "Región": Este de China, Sur de China, Norte de China.
  2. ['销售额'].sum()Indica que solo se aplica la suma agregada a la columna "Ventas".
  3. as_index=True(Valor predeterminado) devuelve una Serie con la región como índice;as_index=Falsedevuelve un DataFrame que conserva la región como columna normal, más adecuado para el procesamiento posterior.

Ejemplo 2: Agrupar por múltiples columnas

A veces es necesario agrupar por varias columnas a la vez, por ejemplo, calcular las ventas por región y producto.

Ejemplo

import pandas as pd

# Crear datos de ventas
data = {
    'Región': ['Norte de China', 'Este de China', 'Sur de China', 'Norte de China', 'Este de China', 'Sur de China', 'Norte de China', 'Este de China'],
    'Producto': ['A', 'B', 'C', 'B', 'A', 'C', 'A', 'B'],
    'Ventas': [1000, 2000, 1500, 1800, 2200, 1600, 1200, 2100]
}
df = pd.DataFrame(data)

print("Datos originales:")
print(df)
print()

# Agrupar por las columnas "Región" y "Producto" y calcular las ventas totales
# Usar una lista para especificar múltiples columnas de agrupación
grouped = df.groupby(['Región', 'Producto'], as_index=False)['Ventas'].sum()

print("Ventas totales después de agrupar por región y producto:")
print(grouped)
print()

# Usar pivot_table para mostrar el resultado de forma más intuitiva
pivot = df.pivot_table(values='Ventas', index='Región', columns='Producto', aggfunc='sum', fill_value=0)
print("Mostrando con pivot_table:")
print(pivot)

Resultado esperado:

原始数据:
  地区  产品   销售额
0  华北   A   1000
1  华东   B   2000
2  华南   C   1500
3  华北   B   1800
4  华东   A   2200
5  华南   C   1600
6  华北   A   1200
7  华东   B   2100

按地区和产品分组后的总销售额:
   地区  产品   销售额
0  华东   A   2200
1  华东   B   4100
2  华南   C   3100
3  华北   A   2200
4  华北   B   1800

使用 pivot_table 展示:
产品      A     B     C
地区
华北   2200  1800     0
华东   2200  4100     0
华南      0     0  3100

Análisis del código:

  • ['región', 'producto']Usar una lista permite agrupar por múltiples columnas a la vez; el resultado genera un índice de varios niveles.
  • as_index=FalseCuando `as_index=False`, las columnas de agrupación se conservan como columnas normales en el resultado, lo que facilita la visualización y el procesamiento posterior.
  • pivot_table()Proporciona una funcionalidad de tabla cruzada similar, que puede presentar los resultados de agrupación de una manera más intuitiva.

Ejemplo 3: Agrupar usando diccionarios y funciones

groupby()No solo se puede agrupar por nombre de columna, sino que también se admite definir reglas de agrupación mediante diccionarios o funciones, lo cual es muy útil cuando se necesita una lógica de agrupación personalizada.

Ejemplo

import pandas as pd

# Crear datos de calificaciones de estudiantes
data = {
    'Nombre': ['Zhang San', 'Li Si', 'Wang Wu', 'Zhao Liu', 'Sun Qi', 'Zhou Ba'],
    'Chino': [85, 92, 78, 88, 95, 82],
    'Matemáticas': [90, 85, 92, 78, 88, 91],
    'Inglés': [88, 90, 85, 92, 87, 89]
}
df = pd.DataFrame(data)

print("Datos originales de calificaciones de estudiantes:")
print(df)
print()

# 1. Usar un diccionario para agrupación personalizada
# Supongamos que queremos agrupar por "apellido" (Zhang, Li, Wang en un grupo; Zhao, Sun, Zhou en otro)
def get_surname_group(name):
    """Devuelve el nombre del grupo según el apellido"""
    if name in ['Zhang San', 'Li Si', 'Wang Wu']:
        return 'Grupo 1'
    else:
        return 'Grupo 2'

# Usar la función apply para agrupar
grouped = df.groupby(get_surname_group).mean(numeric_only=True)
print("Usar una función para agrupación personalizada (calcular el promedio de cada grupo):")
print(grouped)
print()

# 2. Usar un diccionario para mapear la agrupación de una columna específica
# Dividir las calificaciones de Chino en dos grupos según el intervalo numérico: "Excelente" y "Bien"
score_mapping = {
    'Chino': lambda x: 'Excelente' if x >= 90 else 'Bien'
}

# Agrupar la columna de Chino según una condición
grouped_by_score = df.groupby(lambda x: 'Excelente' if df.loc[x, 'Chino'] >= 90 else 'Bien').mean(numeric_only=True)
print("Agrupado por calificaciones de Chino (>=90 es Excelente):")
print(grouped_by_score)

Resultado esperado:

原始学生成绩数据:
   姓名  语文  数学  英语
0  张三   85   90   88
1  李四   92   85   90
2  王五   78   92   85
3  赵六   88   78   92
4  孙七   95   88   87
5  周八   82   91   89

使用函数自定义分组(计算每组平均分):
              语文     数学     英语
姓名
第一组  85.000000  89.000000  87.666667
第二组  88.333333  85.666667  89.333333

按语文成绩分组(>=90为优秀):
              语文     数学     英语
语文
优秀   93.500000  86.500000  88.500000
良好   83.250000  89.500000  88.750000

Análisis del código:

  • La agrupación con funciones personalizadas puede manejar lógica de agrupación compleja; basta con que la función devuelva un valor para agrupar.
  • Usar el parámetronumeric_only=Truepermite realizar cálculos de agregación solo en columnas numéricas, evitando errores al operar sobre columnas no numéricas (como nombres).
  • Mediante la asignación con diccionarios se puede satisfacer la necesidad de "dividir diferentes columnas en diferentes grupos según condiciones".

Ejemplo 4: Iteración después de agrupar

A veces necesitamos realizar operaciones personalizadas más complejas en cada grupo; en ese caso, podemos iterar sobre el objeto de grupo.

Ejemplo

import pandas as pd

# Crear datos de ventas
data = {
    'Región': ['Norte de China', 'Este de China', 'Sur de China', 'Norte de China', 'Este de China', 'Sur de China'],
    'Producto': ['A', 'B', 'C', 'B', 'A', 'C'],
    'Ventas': [1000, 2000, 1500, 1800, 2200, 1600]
}
df = pd.DataFrame(data)

print("Datos originales:")
print(df)
print()

# Iterar sobre cada grupo para procesarlo
print("Información detallada de cada grupo:")
print("-" * 40)

for group_name, group_data in df.groupby('Región'):
    print(f"nNombre del grupo: {group_name}")
    print(f"Número de filas de datos de este grupo: {len(group_data)}")
    print(f"Ventas totales de este grupo: {group_data['销售额'].sum()}")
    print(fVentas promedio de este grupo: {group_data['Ventas'].mean():.2f})
    print("-" * 40)

Resultado esperado de la ejecución:

原始数据:
  地区  产品   销售额
0  华东   B   2000
1  华南   C   1500
2  华北   A   1000
3  华东   B   1800
4  华南   C   2200
5  华北   B   1800

每个分组的详细信息:
----------------------------------------

分组名称: 华东
该组数据行数: 2
该组销售总额: 3800
该组平均销售额: 1900.00
----------------------------------------

分组名称: 华南
该组数据行数: 2
3700
1850.00
----------------------------------------

分组名称: 华北
该组数据行数: 2
2800
1400.00
----------------------------------------

Análisis del código:

  • groupby()El objeto de grupo devuelto se puede iterar directamente; cada iteración devuelve una tupla: (nombre del grupo, datos del grupo).
  • De esta manera, se pueden realizar operaciones personalizadas arbitrariamente complejas en cada grupo.
  • En aplicaciones prácticas, este método se utiliza comúnmente para generar informes complejos o realizar limpieza de datos.

Consejo:groupby()El objeto GroupBy devuelto es de "ejecución diferida" (lazy), no calcula los resultados de inmediato. Solo al llamar funciones de agregación (comosum()、mean()、count()etc.) o al iterar, es cuando realmente se ejecuta el cálculo.


Funciones comunes de Pandas

Otras extensiones