Ir al contenido principal

Índices jerárquicos, groupby y pandas

En este tutorial aprenderás qué son los multiíndices en DataFrames de pandas y cómo surgen de forma natural a partir de operaciones groupby en datos reales.
Actualizado 17 sept 2026  · 9 min leer

Explorar con IA

ChatGPTClaudePerplexity

En una entrada anterior, viste cómo la operación groupby surge de forma natural al aplicar el principio de dividir-aplicar-combinar (split-apply-combine). Exploraste un conjunto de datos con valoraciones de usuarios de Netflix y agrupaste las filas por año de estreno de la película para generar la siguiente figura:

pandas groupby

Esto se consiguió agrupando por una sola columna. Comenté de pasada que quizá quieras agrupar por varias columnas; en ese caso, el DataFrame de pandas resultante acaba con un multiíndice o índice jerárquico. En esta entrada aprenderás qué son los índices jerárquicos y verás cómo aparecen al agrupar por varias variables de tus datos. Puedes profundizar en estos conceptos y prácticas en nuestro curso Manipulating DataFrames with pandas.

Empecemos: ¿qué son los índices jerárquicos?

índice jerárquico pandas

Índices jerárquicos y DataFrames de pandas

¿Qué es el índice de un DataFrame?

Antes de presentar los índices jerárquicos, recuerda qué es el índice de un DataFrame de pandas. El índice de un DataFrame es un conjunto de etiquetas, una por cada fila. Veamos un ejemplo. Primero voy a importar un conjunto de datos sintético con la actividad en DataCamp de Ellie, una estudiante ficticia de DataCamp. Las columnas son una fecha, un lenguaje de programación y el número de ejercicios que Ellie completó ese día en ese lenguaje. Carga los datos:

# Import pandas
import pandas as pd

# Load in data
df = pd.read_csv('data/user_ex_python.csv')
df
 

Ejecuta y edita el código de este tutorial en línea

Ejecutar código
  date language ex_complete
0 2017-01-01 python 6
1 2017-01-02 python 5
2 2017-01-03 python 10

Puedes ver el índice en el lado izquierdo del DataFrame y que está compuesto por enteros. Es un RangeIndex:

# Check out index
df.index
RangeIndex(start=0, stop=3, step=1)

Podemos usar este índice para extraer una o varias filas de df:

# Slice and dice data
df.loc[:1]
  date language ex_complete
0 2017-01-01 python 6
1 2017-01-02 python 5

Sin embargo, este índice no aporta mucha información. Si vas a etiquetar las filas de tu DataFrame, lo ideal es hacerlo de forma significativa, siempre que sea posible. ¿Se puede con este conjunto de datos? Una buena forma de enfocarlo es que necesitas un identificador único y significativo para cada fila. Revisa las columnas y comprueba si alguna cumple estos criterios. Observa que la columna date contiene fechas únicas, así que tiene sentido etiquetar cada fila con la fecha. Es decir, puedes convertir la columna date en el índice del DataFrame con el método .set_index() (nota: inplace=True indica que realmente modificas el DataFrame df en el sitio):

# Set new index
df.set_index(pd.DatetimeIndex(df['date']), inplace=True)
df
  date language ex_complete
date      
2017-01-01 2017-01-01 python 6
2017-01-02 2017-01-02 python 5
2017-01-03 2017-01-03 python 10

Esto le da a df un DateTimeIndex:

# Check out new index
df.index
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03'], dtype='datetime64[ns]', name='date', freq=None)

Ahora puedes extraer filas usando el DateTimeIndex que acabas de crear:

# Slice and dice data w/ new index
df.loc['2017-01-02']
date           2017-01-02
language           python
ex_complete             5
Name: 2017-01-02 00:00:00, dtype: object

Ten en cuenta también que el atributo .columns devuelve un índice con los nombres de las columnas de df:

# Check out columns
df.columns
Index(['date', 'language', 'ex_complete'], dtype='object')

Esto puede resultar algo confuso porque lo que indica es que df.columns es de tipo Index. Esto no significa que las columnas sean el índice del DataFrame. El índice de df siempre lo da df.index. Revisa nuestro tutorial de DataFrames de pandas para saber más sobre índices. Ahora es momento de conocer los índices jerárquicos.

El multiíndice de un DataFrame de pandas

¿Y si tuviéramos varios lenguajes en nuestro conjunto de datos, como ocurre en DataCamp? Mira:

# Import and check out data
df = pd.read_csv('data/user_ex.csv')
df
  date language ex_complete
0 2017-01-01 python 6
1 2017-01-02 python 5
2 2017-01-03 python 10
3 2017-01-01 r 8
4 2017-01-02 r 8
5 2017-01-03 r 8

Ahora cada fecha corresponde a varias filas, una por lenguaje. Por ejemplo, la fecha «2017-01-02» aparece en las filas 1 y 4, para los lenguajes Python y R, respectivamente. Por tanto, la fecha ya no identifica la fila de forma única. Sin embargo, «date» y «language» juntas sí identifican las filas de forma única. Por eso usamos ambas como índice:

# Set index
df.set_index(['date', 'language'], inplace=True)
df
    ex_complete
date language  
2017-01-01 python 6
2017-01-02 python 5
2017-01-03 python 10
2017-01-01 r 8
2017-01-02 r 8
2017-01-03 r 8

Acabas de crear un multiíndice, o índice jerárquico (familiarízate con ambos términos porque se usan indistintamente). Puedes comprobarlo así:

# Check out multi-index
df.index
MultiIndex(levels=[['2017-01-01', '2017-01-02', '2017-01-03'], ['python', 'r']],
           labels=[[0, 1, 2, 0, 1, 2], [0, 0, 0, 1, 1, 1]],
           names=['date', 'language'])

Lo anterior indica que tu DataFrame df ahora tiene un MultiIndex con dos niveles, el primero por fecha y el segundo por lenguaje. Recuerda que arriba podías cortar el DataFrame usando el índice y el accesor .loc: df.loc['2017-01-02']. Para poder hacer slicing con un multiíndice, primero necesitas ordenar el índice:

# Sort index
df.sort_index(inplace=True)
df
    ex_complete
date language  
2017-01-01 python 6
r 8
2017-01-02 python 5
r 8
2017-01-03 python 10
r 8

Ahora puedes extraer el número de ejercicios de R completados el 2017-01-02 pasando una tupla al accesor .loc:

# Slice & dice your DataFrame
df.loc[('2017-01-02', 'r')]

ex_complete 8 Name: (2017-01-02, r), dtype: int64

Cuándo y por qué usar multiíndices

Los multiíndices son una herramienta potente para analizar y organizar datos en pandas. Permiten crear índices jerárquicos que pueden usarse para agrupar y agregar datos en múltiples dimensiones. Son especialmente útiles con conjuntos de datos complejos que tienen varios niveles de categorización, como datos financieros o series temporales.

Al crear un multiíndice, puedes agrupar por varias variables a la vez, lo que puede desvelar patrones que no se aprecian con una agrupación de un solo nivel. Por ejemplo, puedes agrupar por tiempo y ubicación a la vez y así analizar tendencias por regiones a lo largo del tiempo.

Además, los multiíndices facilitan seleccionar y filtrar datos de forma eficiente, ya que el índice ofrece una vía cómoda para acceder a subconjuntos específicos. En resumen, son clave para organizar, agrupar y analizar datasets complejos en pandas y resultan imprescindibles para cualquier analista o científico de datos que trabaje con datos jerárquicos.

Ya sabes algo sobre índices jerárquicos (o multiíndices). Veamos ahora cómo aparecen al trabajar con objetos groupby.

Índices jerárquicos, objetos groupby y dividir-aplicar-combinar

En una entrada anterior exploramos los objetos groupby y el principio analítico de dividir-aplicar-combinar usando datos de Netflix. Hagamos un repaso rápido con otro conjunto de datos: tips, que viene incluido en el paquete seaborn. «Tips» contiene variables como tip, total_bill, el día de la semana y la franja horaria. Primero carga y explora los datos:

# Import and check out data
import seaborn as sns
tips = sns.load_dataset("tips")
tips.head()
  total_bill tip sex smoker day time size
0 16.99 1.01 Female No Sun Dinner 2
1 10.34 1.66 Male No Sun Dinner 3
2 21.01 3.50 Male No Sun Dinner 3
3 23.68 3.31 Male No Sun Dinner 2
4 24.59 3.61 Female No Sun Dinner 4

Observa que el índice de tips es un RangeIndex:

# Check out index
tips.index
RangeIndex(start=0, stop=244, step=1)

Siempre ayuda hacer algo de EDA visual antes de ponerte a calcular, y la función pairplot de seaborn te permite ver de un vistazo todas las variables numéricas:

# Import pyplot, figures inline, set style, plot pairplot
import matplotlib.pyplot as plt
%matplotlib inline
sns.set()
sns.pairplot(tips, hue='day');

gráficos diversos

Si quieres comparar la propina media entre «smokers» y «non-smokers», puedes dividir el DataFrame original por «smoker» (usando groupby), aplicar la función «mean» y combinar en un nuevo DataFrame:

# Get mean of smoker/non-smoker groups
df = tips.groupby('smoker').mean()
df
  total_bill tip size
smoker      
Yes 20.756344 3.008710 2.408602
No 19.188278 2.991854 2.668874

El índice resultante del DataFrame df es la columna «smoker» del DataFrame original «tips»:

# Check out new index
df.index
CategoricalIndex(['Yes', 'No'], categories=['Yes', 'No'], ordered=False, name='smoker', dtype='category')

Si quieres, puedes restablecer el índice para que «smoker» vuelva a ser una columna del DataFrame:

# Reset the index
df.reset_index()
  smoker total_bill tip size
0 Yes 20.756344 3.008710 2.408602
1 No 19.188278 2.991854 2.668874

Ahora verás cómo los índices jerárquicos surgen de dividir-aplicar-combinar y de las operaciones groupby.

Agrupaciones múltiples e índices jerárquicos

Antes agrupaste el conjunto tips según la variable «smoker». A veces necesitarás agrupar un conjunto de datos por dos variables. Por ejemplo, es natural agrupar tips en fumadores/no fumadores y cena/comida. Para hacerlo, pasa los nombres de las columnas por las que quieres agrupar como una lista:

# Group by two columns
df = tips.groupby(['smoker','time']).mean()
df
    total_bill tip size
smoker time      
Yes Lunch 17.399130 2.834348 2.217391
Dinner 21.859429 3.066000 2.471429
No Lunch 17.050889 2.673778 2.511111
Dinner 20.095660 3.126887 2.735849

Como puedes ver, tanto «smoker» como «time» son índices de df. Tiene sentido: si al agrupar por «smoker» el índice pasa a ser esa columna original, al agrupar por dos columnas obtienes dos índices. Compruébalo para confirmar que es jerárquico:

# Check out index
df.index
MultiIndex(levels=[['Yes', 'No'], ['Lunch', 'Dinner']],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=['smoker', 'time'])

Y así es. Ahora puedes hacer un buen puñado de cosas útiles, como obtener los recuentos en cada agrupación:

# Group by two features
tips.groupby(['smoker','time']).size()
smoker  time  
Yes     Lunch      23
        Dinner     70
No      Lunch      45
        Dinner    106
dtype: int64

También puedes intercambiar los niveles del índice jerárquico para que «time» aparezca antes que «smoker» en el índice:

# Swap levels of multi-index
df.swaplevel()
    total_bill tip size
time smoker      
Lunch Yes 17.399130 2.834348 2.217391
Dinner Yes 21.859429 3.066000 2.471429
Lunch No 17.050889 2.673778 2.511111
Dinner No 20.095660 3.126887 2.735849

Después quizá quieras quitar una de estas variables del índice jerárquico y formar columnas distintas con respecto a esa variable. Puedes hacerlo con el método unstack:

# Unstack your multi-index
df.unstack()
  total_bill tip size
time Lunch Dinner Lunch Dinner Lunch Dinner
smoker            
Yes 17.399130 21.859429 2.834348 3.066000 2.217391 2.471429
No 17.050889 20.095660 2.673778 3.126887 2.511111 2.735849

Puedes «desapilar» por la variable externa del índice usando el argumento de palabra clave «level»:

# Unsstack the outer index
df.unstack(level=0)
  total_bill tip size
smoker Yes No Yes No Yes No
time            
Lunch 17.399130 17.050889 2.834348 2.673778 2.217391 2.511111
Dinner 21.859429 20.095660 3.066000 3.126887 2.471429 2.735849

El resultado de «desapilar» tiene un índice no jerárquico, como cabría esperar:

# Check out index
df.unstack().index
CategoricalIndex(['Yes', 'No'], categories=['Yes', 'No'], ordered=False, name='smoker', dtype='category')

Como resultado, ahora puedes realizar todo tipo de análisis con respecto a estas agrupaciones. Te animo a hacerlo.

Índices jerárquicos en el día a día

En esta entrada has conocido los índices jerárquicos (o multiíndices) y has visto cómo surgen de forma natural cuando quieres que el índice de un DataFrame etiquete las filas de forma única y con sentido. También has visto cómo aparecen cuando necesitas agrupar tus datos por varias columnas, aplicando el principio de dividir-aplicar-combinar. Espero que disfrutes trabajando con índices jerárquicos.

Esta entrada se generó a partir de un Jupyter Notebook; puedes encontrarla en este repositorio. Si tienes ideas, comentarios o reflexiones, escríbeme en Twitter: @hugobowne.

Echa un vistazo a otros tutoriales útiles de pandas en DataCamp, como:

Temas
Python
Ciencia de datos

Aprende más sobre Python y pandas

Curso

Uniones en pandas para usuarios de hojas de cálculo

4 h
4.5K
Aprende a unir de forma eficaz y eficiente conjuntos de datos en formato tabular utilizando la biblioteca Pandas de Python.
Ver detallesRight Arrow
Iniciar Curso
Ver másRight Arrow
Relacionado
data-frames-in-python-banner_cgzjxy.jpeg

Tutorial

Tutorial de Pandas: DataFrames en Python

Explora el análisis de datos con Python. Los DataFrames de Pandas facilitan la manipulación de tus datos, desde la selección o sustitución de columnas e índices hasta la remodelación de tus datos.
Karlijn Willems's photo

Karlijn Willems

15 min

Tutorial

Tutorial de unión de DataFrames en pandas

En este tutorial, usted aprenderá varias maneras en las que múltiples DataFrames pueden ser fusionados en python usando la librería Pandas.
DataCamp Team's photo

DataCamp Team

13 min

Tutorial

Tutorial seleccionar columnas con Python

Utiliza Python Pandas y selecciona columnas de los DataFrames. ¡Sigue nuestro tutorial con ejemplos de código y aprende hoy mismo distintas formas de seleccionar tus datos!
DataCamp Team's photo

DataCamp Team

7 min

Tutorial

Tutorial de pandas en Python: La guía definitiva para principiantes

¿Estás preparado para comenzar tu viaje de pandas? Aquí tienes una guía paso a paso sobre cómo empezar.
Vidhi Chugh's photo

Vidhi Chugh

15 min

Tutorial

Aprendizaje automático de datos categóricos con el tutorial de Python

Aprenda los trucos más comunes para manejar datos categóricos y preprocesarlos para construir modelos de aprendizaje automático.
Moez Ali's photo

Moez Ali

14 min

Tutorial

Tutorial de Estructuras de Datos en Python

Introdúcete en las estructuras de datos de Python: aprende más sobre tipos de datos y estructuras de datos primitivas y no primitivas, como cadenas, listas, pilas, etc.
Sejal Jaiswal's photo

Sejal Jaiswal

24 min

Ver MásVer Más