Función df.groupby() 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 (como
sum()、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
# 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:
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.['销售额'].sum()Indica que solo se aplica la suma agregada a la columna "Ventas".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
# 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
# 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ámetro
numeric_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
# 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.
Otras extensiones