Búsqueda de sitios web

Cómo restablecer el índice de un DataFrame de pandas


En este tutorial, aprenderá cómo restablecer un índice de Pandas DataFrame, las razones por las que podría querer hacerlo y los problemas que podrían ocurrir si no lo hace.

Antes de comenzar su viaje de aprendizaje, debe familiarizarse con cómo crear un DataFrame de pandas. Conocer la diferencia entre un DataFrame y una serie pandas también le resultará útil.

Además, es posible que desee utilizar la herramienta de análisis de datos Jupyter Notebook mientras trabaja en los ejemplos de este tutorial. Alternativamente, JupyterLab le brindará una experiencia de computadora portátil mejorada, pero siéntase libre de usar cualquier entorno Python que desee.

Como punto de partida, necesitará algunos datos. Para empezar, utilizará el archivo band_members.csv incluido en los materiales descargables al que puede acceder haciendo clic en el siguiente enlace:

La siguiente tabla describe los datos de band_members.csv con los que comenzará:

Column Name PyArrow Data Type Description
first_name string First name of member
last_name string Last name of member
instrument string Main instrument played
date_of_birth string Member’s date of birth

Como verás, los datos tienen detalles de los integrantes de la banda de rock The Beach Boys. Cada fila contiene información sobre sus distintos miembros, tanto pasados como presentes.

A lo largo de este tutorial, utilizará la biblioteca pandas para permitirle trabajar con DataFrames, así como la biblioteca PyArrow más nueva. La biblioteca PyArrow proporciona a pandas sus propios tipos de datos optimizados, que son más rápidos y consumen menos memoria que los tipos NumPy tradicionales que pandas usa de forma predeterminada.

Si está trabajando en la línea de comando, puede instalar pandas y pyarrow usando el comando único python -m pip install pandas pyarrow. Si está trabajando en un Jupyter Notebook, debe usar !python -m pip install pandas pyarrow. De todos modos, debe hacer esto dentro de un entorno virtual para evitar conflictos con las bibliotecas que utiliza en su entorno global.

Una vez que tenga las bibliotecas en su lugar, es hora de leer sus datos en un DataFrame:

>>> import pandas as pd

>>> beach_boys = pd.read_csv(
...     "band_members.csv"
... ).convert_dtypes(dtype_backend="pyarrow")

Primero, usaste import pandas para que la biblioteca estuviera disponible dentro de tu código. Para construir el DataFrame y leerlo en la variable beach_boys, usaste la función read_csv() de pandas, pasando band_members.csv como el archivo a leer. Finalmente, al pasar dtype_backend="pyarrow" a .convert_dtypes(), convierte todas las columnas a tipos pyarrow.

Si desea verificar que los tipos de datos pyarrow realmente se están utilizando, entonces beach_boys.dtypes satisfará su curiosidad:

>>> beach_boys.dtypes
first_name            string[pyarrow]
last_name             string[pyarrow]
instrument            string[pyarrow]
date_of_birth         string[pyarrow]
dtype: object

Como puede ver, cada tipo de datos contiene [pyarrow] en su nombre.

Si desea analizar la información de la fecha a fondo, entonces debería analizar la columna date_of_birth para asegurarse de que las fechas se lean como un tipo de fecha pyarrow adecuado. Esto le permitiría analizar por días, meses o años específicos, etc., como se encuentra comúnmente en las tablas dinámicas.

La columna date_of_birth no se analiza en este tutorial, por lo que el tipo de datos string que se lee servirá. Más adelante, tendrás la oportunidad de perfeccionar tus habilidades con algunos ejercicios. Las soluciones incluyen el código de análisis de fecha si desea ver cómo se hace.

Ahora que el archivo se ha cargado en un DataFrame, probablemente querrás echarle un vistazo:

>>> beach_boys
  first_name last_name instrument date_of_birth
0      Brian    Wilson       Bass   20-Jun-1942
1       Mike      Love  Saxophone   15-Mar-1941
2         Al   Jardine     Guitar   03-Sep-1942
3      Bruce  Johnston       Bass   27-Jun-1942
4       Carl    Wilson     Guitar   21-Dec-1946
5     Dennis    Wilson      Drums   04-Dec-1944
6      David     Marks     Guitar   22-Aug-1948
7      Ricky    Fataar      Drums   05-Sep-1952
8    Blondie   Chaplin     Guitar   07-Jul-1951

Los DataFrames son estructuras de datos bidimensionales similares a hojas de cálculo o tablas de bases de datos. Un DataFrame de pandas puede considerarse un conjunto de columnas, y cada columna es una serie de pandas. Cada columna también tiene un encabezado, que es la propiedad name de la Serie, y cada fila tiene una etiqueta, a la que se hace referencia como un elemento de su objeto de índice asociado.

El índice del DataFrame se muestra a la izquierda del DataFrame. No forma parte del archivo fuente original band_members.csv, pero se agrega como parte del proceso de creación del DataFrame. Es este objeto de índice el que estás aprendiendo a restablecer.

El índice de un DataFrame es una columna adicional de etiquetas que le ayuda a identificar filas. Cuando se usa en combinación con encabezados de columna, le permite acceder a datos específicos dentro de su DataFrame. Las etiquetas de índice predeterminadas son una secuencia de números enteros, pero puedes usar cadenas para hacerlas más significativas. De hecho, puedes usar cualquier tipo hash para tu índice, pero los números enteros, cadenas y marcas de tiempo son los más comunes.

Una vez superados estos preliminares, es hora de llevar tu Little Deuce Coupe a la playa, hacer un pop-up y aprender a navegar. Ahora investigará las principales formas de volver a indexar un DataFrame. Puede aplicar un objeto Index directamente a la propiedad .index del DataFrame, o usar el método .set_axis() del DataFrame. Para empezar, utilizará el método .reset_index() del DataFrame.

Cómo restablecer un índice de DataFrame de pandas con .reset_index()

El método DataFrame.reset_index(), como su nombre indica, se utiliza para restablecer el índice de un DataFrame de pandas a su valor predeterminado. También puede utilizar este método para restablecer el MultiIndex en su DataFrame si tiene uno. Aprenderá más sobre cómo restablecer índices múltiples más adelante.

Supongamos que ha estado realizando una limpieza de datos en su DataFrame y ha decidido ordenarlo alfabéticamente por first_name. Puedes hacer esto usando .sort_values():

>>> beach_boys.sort_values(by="first_name")
  first_name last_name instrument date_of_birth
2         Al   Jardine     Guitar   03-Sep-1942
8    Blondie   Chaplin     Guitar   07-Jul-1951
0      Brian    Wilson       Bass   20-Jun-1942
3      Bruce  Johnston       Bass   27-Jun-1942
4       Carl    Wilson     Guitar   21-Dec-1946
6      David     Marks     Guitar   22-Aug-1948
5     Dennis    Wilson      Drums   04-Dec-1944
1       Mike      Love  Saxophone   15-Mar-1941
7      Ricky    Fataar      Drums   05-Sep-1952

Si bien está contento de que la clasificación haya funcionado perfectamente, no está satisfecho con el estado actual de su índice. El índice ya no guarda ningún parecido con el orden actualizado de las filas.

Para solucionar este problema, su primera idea podría ser utilizar .reset_index() con sus parámetros predeterminados, pero es posible que el resultado no sea el que desea:

>>> beach_boys.sort_values(by="first_name").reset_index()
   index first_name last_name instrument date_of_birth
0      2         Al   Jardine     Guitar   03-Sep-1942
1      8    Blondie   Chaplin     Guitar   07-Jul-1951
2      0      Brian    Wilson       Bass   20-Jun-1942
3      3      Bruce  Johnston       Bass   27-Jun-1942
4      4       Carl    Wilson     Guitar   21-Dec-1946
5      6      David     Marks     Guitar   22-Aug-1948
6      5     Dennis    Wilson      Drums   04-Dec-1944
7      1       Mike      Love  Saxophone   15-Mar-1941
8      7      Ricky    Fataar      Drums   05-Sep-1952

Ahora tiene un nuevo índice predeterminado, que es una serie secuencial de números que comienza en cero y que define claramente el orden de las filas. Sin embargo, el índice original se mantuvo y se movió a una nueva columna que se llama confusamente index. Esto puede ser aceptable si necesita devolver el DataFrame a su orden de clasificación original en el futuro, pero la mayoría de las veces, su inclusión solo desperdicia memoria. Generalmente querrás deshacerte de él.

Afortunadamente, esto es fácil de hacer. De forma predeterminada, .reset_index() hace una copia del DataFrame original, aplica el índice predeterminado a esta segunda copia y le devuelve esa segunda copia. Esto significa que el índice del DataFrame original permanece sin cambios, por lo que no se le ha causado ningún daño.

Puede indicarle a .reset_index() que elimine el índice original por completo y lo reemplace con uno nuevo predeterminado estableciendo su parámetro drop en True. También puede reasignar la referencia original al nuevo DataFrame. La versión actualizada será la única que exista a partir de este momento:

>>> beach_boys = (
...     beach_boys.sort_values(by="first_name")
...     .reset_index(drop=True)
... )
>>> beach_boys
  first_name last_name instrument date_of_birth
0         Al   Jardine     Guitar   03-Sep-1942
1    Blondie   Chaplin     Guitar   07-Jul-1951
2      Brian    Wilson       Bass   20-Jun-1942
3      Bruce  Johnston       Bass   27-Jun-1942
4       Carl    Wilson     Guitar   21-Dec-1946
5      David     Marks     Guitar   22-Aug-1948
6     Dennis    Wilson      Drums   04-Dec-1944
7       Mike      Love  Saxophone   15-Mar-1941
8      Ricky    Fataar      Drums   05-Sep-1952

Ahora ha ordenado su DataFrame de la manera que desea. También reasignó la referencia original al nuevo DataFrame, lo que significa que la irritante columna index se ha hundido sin dejar rastro.

Ahora es el momento de que te diviertas un poco y pruebes el siguiente desafío:

Ya has visto cómo es posible restablecer un índice conservando el anterior. Cuando haces esto, pandas lo agrega como una nueva columna con el título index. Eche un vistazo a la documentación de .reset_index() y vea si puede descubrir cómo personalizar el nombre de esta nueva columna.

Ahora vuelva a leer los datos de band_members.csv en un DataFrame nuevo y use beach_boys.index=range(1, 10) para actualizar su índice. Finalmente, use .reset_index() para ver si puede personalizar su DataFrame y hacer que se vea así:

>>> beach_boys
   old_index first_name last_name instrument date_of_birth
0          1      Brian    Wilson       Bass   20-Jun-1942
1          2       Mike      Love  Saxophone   15-Mar-1941
2          3         Al   Jardine     Guitar   03-Sep-1942
3          4      Bruce  Johnston       Bass   27-Jun-1942
4          5       Carl    Wilson     Guitar   21-Dec-1946
5          6     Dennis    Wilson      Drums   04-Dec-1944
6          7      David     Marks     Guitar   22-Aug-1948
7          8      Ricky    Fataar      Drums   05-Sep-1952
8          9    Blondie   Chaplin     Guitar   07-Jul-1951

Su objetivo es asegurarse de que el índice existente no sólo se conserve, sino que también se le cambie el nombre.

Encontrará una solución en el cuaderno Solutions.ipynb que se proporciona en los materiales descargables.

Aunque el método .reset_index() que acaba de conocer es la forma más personalizable de restablecer un índice de Pandas DataFrame, lo que le permite manejar índices múltiples, ciertamente no es la única forma. Es posible hacerlo a la manera gremmie utilizando los primeros principios.

Restablecer un índice directamente con .index

Al trabajar con DataFrames, puede identificar filas usando .loc[] o .iloc[]. Cada uno tiene su caso de uso, aunque cualquiera puede usarse en cualquier DataFrame.

Se hace referencia al índice de un DataFrame mediante su propiedad .index. Para reemplazar el índice actual con uno propio, asigna a .index un iterable que contiene tus nuevas etiquetas de índice. Esto le permite muchas posibilidades para personalizar sus índices de DataFrame más allá de los números incrementales predeterminados.

Antes de explorar .loc[] y .iloc[], agregará un índice personalizado a su DataFrame que contenga las iniciales de los miembros de la banda Beach Boys. Primero, leerás los datos de los miembros de la banda desde un archivo CSV y los convertirás a tipos de datos pyarrow:

>>> beach_boys = pd.read_csv(
...     "band_members.csv"
... ).convert_dtypes(dtype_backend="pyarrow")

>>> initials = ["BW", "ML", "AJ", "BJ", "CW", "DW", "DM", "RF", "BC"]
>>> beach_boys.index = initials
>>> beach_boys
   first_name last_name instrument date_of_birth
BW      Brian    Wilson       Bass   20-Jun-1942
ML       Mike      Love  Saxophone   15-Mar-1941
AJ         Al   Jardine     Guitar   03-Sep-1942
BJ      Bruce  Johnston       Bass   27-Jun-1942
CW       Carl    Wilson     Guitar   21-Dec-1946
DW     Dennis    Wilson      Drums   04-Dec-1944
DM      David     Marks     Guitar   22-Aug-1948
RF      Ricky    Fataar      Drums   05-Sep-1952
BC    Blondie   Chaplin     Guitar   07-Jul-1951

En breve veremos una forma alternativa de restablecer un índice, pero primero profundizaremos en la selección de filas.

Seleccione filas usando .loc[] y .iloc[]

El atributo .loc[] le permite indexar filas por su etiqueta de índice. Esto es particularmente útil cuando las etiquetas de índice subyacentes tienen un significado intrínseco dentro del DataFrame, como nombres de usuario o marcas de tiempo.

Si divide con .loc[], utiliza un intervalo cerrado, lo que significa que los valores de índice inicial y final que especifique aparecerán en la salida. Entonces, al seleccionar una porción de filas por nombre de usuario, su salida mostrará la primera, la última y todo lo demás.

El atributo .iloc[] le permite buscar filas según su posición de índice, independientemente del valor de la etiqueta de índice. Cuando utiliza .iloc[], utiliza indexación de base cero. En otras palabras, la primera fila está en la ubicación 0, no en 1 como cabría esperar. .iloc[] utiliza un intervalo abierto, lo que significa que si bien el valor del índice inicial que especifique aparecerá en la salida, el final no.

Si bien estos conceptos le resultarán muy familiares si alguna vez ha dividido una cadena o una lista, es importante tener en cuenta que el elemento final .iloc[] parece para seleccionar won. En realidad no será seleccionado.

Por supuesto, no importa si usa .iloc[] o .loc[] si está tratando con índices predeterminados porque estos también usan secuencias de base cero. , por lo que sus etiquetas y posiciones coinciden. Sin embargo, si su índice contiene cadenas o una secuencia numérica no predeterminada, los parámetros pasados a .iloc[] no se parecerán al valor de índice real de la fila a la que está accediendo, lo que dificultará su código. para leer.

Ahora que su DataFrame se ha actualizado con un índice nuevo, puede usarlo para seleccionar algunas filas usando .loc[] y .iloc[]:

>>> beach_boys = pd.read_csv(
...     "band_members.csv"
... ).convert_dtypes(dtype_backend="pyarrow")

>>> initials = ["BW", "ML", "AJ", "BJ", "CW", "DW", "DM", "RF", "BC"]
>>> beach_boys.index = initials

>>> beach_boys.loc[["BW"]]
   first_name last_name instrument date_of_birth
BW      Brian    Wilson       Bass   20-Jun-1942

>>> beach_boys.iloc[[1]]
   first_name last_name instrument date_of_birth
ML       Mike      Love  Saxophone   15-Mar-1941

>>> beach_boys.loc["BW":"BJ"]
   first_name last_name instrument date_of_birth
BW      Brian    Wilson       Bass   20-Jun-1942
ML       Mike      Love  Saxophone   15-Mar-1941
AJ         Al   Jardine     Guitar   03-Sep-1942
BJ      Bruce  Johnston       Bass   27-Jun-1942

>>> beach_boys.iloc[1:4]
   first_name last_name instrument date_of_birth
ML       Mike      Love  Saxophone   15-Mar-1941
AJ         Al   Jardine     Guitar   03-Sep-1942
BJ      Bruce  Johnston       Bass   27-Jun-1942

En la línea 8, accedió a la primera fila cuyo valor de índice es BW pasándolo como una cadena a .loc[]. Al pasarlo como una lista a .loc[["BW"]], su salida se convierte en un DataFrame. Podrías haberlo pasado directamente, pero esto habría producido una serie de pandas que se comporta de manera diferente. El punto principal a tener en cuenta es que al pasar un valor de índice a .loc[], devuelve la fila cuya etiqueta de índice es ese valor.

Compare esto con el resultado después de la línea 12. El código accede a la fila número 1, esta vez con .iloc[[1]]. Observe cómo la salida es diferente. Usar .iloc[[1]] significa que ha seleccionado la segunda fila del DataFrame. Recuerde, .iloc[] trata la primera fila del DataFrame como 0, independientemente de la etiqueta de índice real.

En la línea 16, seleccionó las primeras cuatro filas pasando las etiquetas de la primera y cuarta filas a .loc[].

Finalmente, cuando pasó el segmento 1:4 a .iloc[] en la línea 23, seleccionó las filas que comenzaban en la posición uno del índice; en otras palabras, la segunda fila. pero termina en la posición tres del índice. Nuevamente, esto se debe al efecto de numeración basada en cero de las filas y a que el último parámetro de segmento de la posición 4 está excluido. Recuerde que .iloc[] asume un intervalo abierto.

Ahora es el momento de que pruebes otro desafío. Si te equivocas, siempre puedes Hacerlo de nuevo:

Una vez más, vuelva a leer los datos de band_members.csv en un DataFrame nuevo. Ahora, vea si puede crear el DataFrame que se muestra a continuación asignando una lista apropiada a beach_boys.index, luego seleccione las dos filas inferiores usando .loc[] y .iloc[]:

>>> beach_boys
   first_name last_name instrument date_of_birth
2       Brian    Wilson       Bass   20-Jun-1942
4        Mike      Love  Saxophone   15-Mar-1941
6          Al   Jardine     Guitar   03-Sep-1942
8       Bruce  Johnston       Bass   27-Jun-1942
10       Carl    Wilson     Guitar   21-Dec-1946
12     Dennis    Wilson      Drums   04-Dec-1944
14      David     Marks     Guitar   22-Aug-1948
16      Ricky    Fataar      Drums   05-Sep-1952
18    Blondie   Chaplin     Guitar   07-Jul-1951

Esta vez, su índice contiene números pares que comienzan en 2.

Encontrará una solución en el cuaderno Solutions.ipynb que se proporciona en los materiales descargables.

Hasta ahora, ha utilizado .reset_index() y .index para restablecer un índice de DataFrame de pandas. Ahora es el momento de tallar y buscar otra alternativa.

Restablecer un índice directamente con .set_axis()

Una tercera forma de restablecer un índice es utilizar el método .set_axis() del DataFrame. Este método le permite asignar un nuevo objeto RangeIndex a su DataFrame y también le permite cambiar las etiquetas de las columnas.

Para alterar el índice existente de un DataFrame, puede pasar .set_axis() un objeto range utilizando el constructor integrado range(). Esto asignará un intervalo de enteros ascendentes al índice que comienza en cero:

>>> beach_boys = pd.read_csv(
...     "band_members.csv"
... ).convert_dtypes(dtype_backend="pyarrow")

>>> beach_boys.set_axis(range(len(beach_boys)))
  first_name last_name instrument date_of_birth
0      Brian    Wilson       Bass   20-Jun-1942
1       Mike      Love  Saxophone   15-Mar-1941
2         Al   Jardine     Guitar   03-Sep-1942
3      Bruce  Johnston       Bass   27-Jun-1942
4       Carl    Wilson     Guitar   21-Dec-1946
5     Dennis    Wilson      Drums   04-Dec-1944
6      David     Marks     Guitar   22-Aug-1948
7      Ricky    Fataar      Drums   05-Sep-1952
8    Blondie   Chaplin     Guitar   07-Jul-1951

Aquí, usó .set_axis() para restablecer el índice a su valor predeterminado. Para hacer esto, pasó a .set_axis() un range cuya longitud era igual a la del DataFrame original beach_boys. El uso de len() garantiza que haya la cantidad correcta de números para cada fila en el DataFrame. Los números generados tendrán base cero y serán suficientes para cubrir cada fila. Como puede ver, el índice ahora se ha restablecido a su valor predeterminado.

Una vez más es hora de comprobar tu comprensión. No dudes en pedir ayuda a un amigo, pero solo si se llama Rhonda:

Vuelva a leer los datos de band_members.csv. Ahora, use .set_axis() para ver si puede hacer que se vea así:

>>> beach_boys
   first_name last_name instrument date_of_birth
0       Brian    Wilson       Bass   20-Jun-1942
1        Mike      Love  Saxophone   15-Mar-1941
4          Al   Jardine     Guitar   03-Sep-1942
9       Bruce  Johnston       Bass   27-Jun-1942
16       Carl    Wilson     Guitar   21-Dec-1946
25     Dennis    Wilson      Drums   04-Dec-1944
36      David     Marks     Guitar   22-Aug-1948
49      Ricky    Fataar      Drums   05-Sep-1952
64    Blondie   Chaplin     Guitar   07-Jul-1951

Esta vez desea que cada valor del índice predeterminado se eleve al cuadrado.

Como de costumbre, encontrará una solución en el cuaderno Solutions.ipynb que se proporciona en los materiales descargables.

In [1]: import pandas as pd

In [2]: beach_boys = pd.read_csv(
   ...:     "band_members.csv"
   ...: ).convert_dtypes(dtype_backend="pyarrow")

In [3]: %timeit -n 1000 beach_boys.reset_index(drop=True)
22.5 µs ± 1.71 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

In [4]: %timeit -n 1000 beach_boys.index = pd.RangeIndex(len(beach_boys.index))
3.75 µs ± 307 ns per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

In [5]: %timeit -n 1000 beach_boys.set_axis(range(len(beach_boys)))
28.1 µs ± 1.89 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

Como puede ver en estos tres tiempos, si todo lo que necesita es restablecer un índice a su valor predeterminado, asignar un objeto RangeIndex directamente a la propiedad .index de su DataFrame es la forma más rápida. de los tres. También es la única forma de restablecer el índice en el DataFrame original. Las otras dos formas crean una copia que puedes asignar nuevamente a la variable beach_boys. Sin embargo, .reset_index(), aunque lento, ofrece más opciones de configuración.

Tenga en cuenta que las cifras de tiempo exactas serán diferentes de las que se muestran aquí, pero deberían mostrar la misma tendencia.

Ahora que sabes cómo restablecer el índice de un DataFrame, continuarás y aprenderás por qué querrías hacer esto. Todavía no es momento de relajarse.

Restaurar un índice secuencial

Cuando limpia datos antes del análisis, a menudo necesita eliminar ciertas filas de un DataFrame. Por ejemplo, es posible que deba eliminar filas duplicadas u otras filas no deseadas. Cuando los elimina, los valores de índice de las filas también se eliminan. Esto podría dar lugar a que aparezcan lagunas en el índice. Al restablecer el índice, puede solucionar este problema.

Más adelante, en la sección sobre cómo alinear índices de varios DataFrames, aprenderá cómo los valores faltantes en el índice de un DataFrame pueden causar estragos cuando necesita analizar sus datos. Por ahora, arruinarás el índice de tu encantador DataFrame beach_boys:

>>> beach_boys = pd.read_csv(
...     "band_members.csv"
... ).convert_dtypes(dtype_backend="pyarrow")

>>> beach_boys
  first_name last_name instrument date_of_birth
0      Brian    Wilson       Bass   20-Jun-1942
1       Mike      Love  Saxophone   15-Mar-1941
2         Al   Jardine     Guitar   03-Sep-1942
3      Bruce  Johnston       Bass   27-Jun-1942
4       Carl    Wilson     Guitar   21-Dec-1946
5     Dennis    Wilson      Drums   04-Dec-1944
6      David     Marks     Guitar   22-Aug-1948
7      Ricky    Fataar      Drums   05-Sep-1952
8    Blondie   Chaplin     Guitar   07-Jul-1951

>>> beach_boys.drop(labels=[3, 5])
  first_name last_name instrument date_of_birth
0      Brian    Wilson       Bass   20-Jun-1942
1       Mike      Love  Saxophone   15-Mar-1941
2         Al   Jardine     Guitar   03-Sep-1942
4       Carl    Wilson     Guitar   21-Dec-1946
6      David     Marks     Guitar   22-Aug-1948
7      Ricky    Fataar      Drums   05-Sep-1952
8    Blondie   Chaplin     Guitar   07-Jul-1951

Como puede ver, el DataFrame contiene las nueve filas originales de miembros de la banda con un índice predeterminado. Para eliminar algunas filas, utilizó el método .drop() del DataFrame. Las filas que se eliminarán se definieron en la lista de Python proporcionada a su parámetro labels. En este caso, se eliminaron las filas cuya etiqueta de índice es 3 o 5. Mire detenidamente el índice en el resultado generado debajo de la línea 17 y verá que el índice ya no es secuencial.

Para solucionar este problema, puedes utilizar cualquiera de las técnicas que has aprendido hasta ahora. Aquí, usarás .reset_index() que, debido a que no cambia el DataFrame subyacente, significa que puedes reutilizar el DataFrame original indexado limpiamente en ejemplos posteriores:

>>> (
...     beach_boys
...     .drop(labels=[3, 5])
...     .reset_index()
... )
   index first_name last_name instrument date_of_birth
0      0      Brian    Wilson       Bass   20-Jun-1942
1      1       Mike      Love  Saxophone   15-Mar-1941
2      2         Al   Jardine     Guitar   03-Sep-1942
3      4       Carl    Wilson     Guitar   21-Dec-1946
4      6      David     Marks     Guitar   22-Aug-1948
5      7      Ricky    Fataar      Drums   05-Sep-1952
6      8    Blondie   Chaplin     Guitar   07-Jul-1951

Como vio anteriormente, .reset_index() ha agregado un nuevo índice predeterminado a su DataFrame. Sin embargo, todavía no está satisfecho porque su índice original aún permanece, aunque en una nueva columna. Una vez más, necesita ajustar el parámetro drop de .reset_index() para completar el trabajo:

>>> (
...     beach_boys
...     .drop(labels=[3, 5])
...     .reset_index(drop=True)
... )
  first_name last_name instrument date_of_birth
0      Brian    Wilson       Bass   20-Jun-1942
1       Mike      Love  Saxophone   15-Mar-1941
2         Al   Jardine     Guitar   03-Sep-1942
3       Carl    Wilson     Guitar   21-Dec-1946
4      David     Marks     Guitar   22-Aug-1948
5      Ricky    Fataar      Drums   05-Sep-1952
6    Blondie   Chaplin     Guitar   07-Jul-1951

Como puede ver, al configurar drop=True, el índice original ahora no se ve por ninguna parte, pero el nuevo y brillante se ve, bueno, nuevo y brillante.

Una vez más, es hora de comprobar su comprensión. Ah, y si no puedes resolverlo, No te preocupes, bebé:

Para comenzar, vuelva a leer los datos de band_members.csv, luego use beach_boys.drop(labels=[3, 5]) para eliminar algunas de las filas. Acabas de aprender cómo restablecer el índice a su valor predeterminado usando .reset_index(drop=True). Vea si puede hacer esto nuevamente usando cualquiera de las otras dos técnicas que ha aprendido. Tu respuesta debería verse así:

>>> beach_boys
  first_name last_name instrument date_of_birth
0      Brian    Wilson       Bass   20-Jun-1942
1       Mike      Love  Saxophone   15-Mar-1941
2         Al   Jardine     Guitar   03-Sep-1942
3       Carl    Wilson     Guitar   21-Dec-1946
4      David     Marks     Guitar   22-Aug-1948
5      Ricky    Fataar      Drums   05-Sep-1952
6    Blondie   Chaplin     Guitar   07-Jul-1951

Como puede ver, el índice predeterminado ha sido restaurado y el original no se encuentra por ninguna parte.

Al igual que con los otros ejercicios, encontrará una solución en el cuaderno Solutions.ipynb que se proporciona en los materiales descargables.

Todos tus esfuerzos hasta ahora pueden significar que ahora estás viendo una aleta gemela. A continuación, volverá a su tablero y se deshará de esos duplicados.

Eliminar valores de índice duplicados

Quizás le sorprenda saber que los índices a veces pueden tener valores duplicados. No es necesario que sean identificadores únicos. Sin embargo, los duplicados suelen ser algo que conviene evitar porque pueden causar problemas. Afortunadamente, .reset_index() puede encargarse de esto por usted.

Los valores de índice duplicados a menudo surgen cuando se fusionan dos DataFrames. La duplicación puede causar problemas con la selección, el corte y el filtrado de filas incorrectos. Antes de que pueda ver estos problemas, primero debe aplicar algunos valores duplicados a su índice:

>>> beach_boys = pd.read_csv(
...     "band_members.csv"
... ).convert_dtypes(dtype_backend="pyarrow")

>>> guitar_players = beach_boys.query(
...     "instrument == 'Guitar'"
... ).reset_index(drop=True)

>>> guitar_players
  first_name last_name instrument date_of_birth
0         Al   Jardine     Guitar   03-Sep-1942
1       Carl    Wilson     Guitar   21-Dec-1946
2      David     Marks     Guitar   22-Aug-1948
3    Blondie   Chaplin     Guitar   07-Jul-1951

>>> others = beach_boys.query(
...     "instrument != 'Guitar'"
... ).reset_index(drop=True)

>>> others
  first_name last_name instrument date_of_birth
0      Brian    Wilson       Bass   20-Jun-1942
1       Mike      Love  Saxophone   15-Mar-1941
2      Bruce  Johnston       Bass   27-Jun-1942
3     Dennis    Wilson      Drums   04-Dec-1944
4      Ricky    Fataar      Drums   05-Sep-1952

Aquí, ha dividido el DataFrame original en dos nuevos. El DataFrame guitar_players, que se muestra debajo de la línea 9, contiene los registros de los miembros del grupo que tocan la guitarra. El marco de datos others, que se muestra debajo de la línea 20, contiene el resto de los miembros.

Para seleccionar a los guitarristas, pasó la cadena de consulta "instrument == 'Guitar'" a .query() en las líneas 5 a 7, lo que extrae todas las filas donde Los valores de la columna instrumento coinciden con "Guitarra".

Las líneas 16 a 18 usan un código similar que crea un segundo DataFrame que contiene las otras filas. En este caso, músicos que no están marcados como guitarristas.

En ambos casos, se utilizó .reset_index() para garantizar que el índice en ambos DataFrames nuevos fuera secuencial. Esto aseguró que algunos valores de índice idénticos aparecieran en ambos DataFrames. Cuando fusiones ambos, podrías pensar que volverás a tu DataFrame original, pero no lo harás:

>>> all_beach_boys = pd.concat([guitar_players, others])

>>> all_beach_boys
  first_name last_name instrument date_of_birth
0         Al   Jardine     Guitar   03-Sep-1942
1       Carl    Wilson     Guitar   21-Dec-1946
2      David     Marks     Guitar   22-Aug-1948
3    Blondie   Chaplin     Guitar   07-Jul-1951
0      Brian    Wilson       Bass   20-Jun-1942
1       Mike      Love  Saxophone   15-Mar-1941
2      Bruce  Johnston       Bass   27-Jun-1942
3     Dennis    Wilson      Drums   04-Dec-1944
4      Ricky    Fataar      Drums   05-Sep-1952

Ha creado un único DataFrame nuevo usando concat(). Al pasarlo tanto a guitar_players como a others, su nuevo DataFrame all_beach_boys muestra a los nueve miembros originales de la banda una vez más, pero el índice contiene duplicados. Ahora que tiene un DataFrame con índices duplicados, investigará los problemas que esto puede causar.

Supongamos que desea seleccionar la cuarta fila: la fila cuya posición de índice es 3. No puedes usar .loc[] para hacer esto porque el índice duplicado causa problemas. Ejecute el siguiente código y verá el problema:

>>> all_beach_boys.loc[3]
  first_name last_name instrument date_of_birth
3    Blondie   Chaplin     Guitar   07-Jul-1951
3     Dennis    Wilson      Drums   04-Dec-1944

>>> all_beach_boys.iloc[[3]]
  first_name last_name instrument date_of_birth
3    Blondie   Chaplin     Guitar   07-Jul-1951

Eche un vistazo a las líneas resaltadas. Como puede ver, debido a que .loc[] seleccionó filas cuya etiqueta de índice es 3, se devolvieron dos registros. Para solucionar este problema, deberá utilizar .iloc[] para seleccionar la fila única requerida.

Los valores de índice duplicados también causan estragos cuando intenta seleccionar filas contiguas mediante el corte. Supongamos que desea ver las filas en las posiciones de índice tres y cuatro. Su primer intento podría ser probar .loc[]:

>>> all_beach_boys.loc[3:4]
Traceback (most recent call last):
  ...
KeyError: 'Cannot get left slice bound for non-unique label: 3'

>>> all_beach_boys.iloc[3:5]
  first_name last_name instrument date_of_birth
3    Blondie   Chaplin     Guitar   07-Jul-1951
0      Brian    Wilson       Bass   20-Jun-1942

Como puede ver, cuando intenta pasar las posiciones de índice requeridas a .loc[], genera una excepción KeyError porque tiene una etiqueta no única. Para solucionar este problema, deberá recurrir al uso de .iloc[] en su lugar.

>>> all_beach_boys.sort_index().loc[3:4]
  first_name last_name instrument date_of_birth
3    Blondie   Chaplin     Guitar   07-Jul-1951
3     Dennis    Wilson      Drums   04-Dec-1944
4      Ricky    Fataar      Drums   05-Sep-1952

Como puede ver, se han devuelto las filas con etiquetas de índice 3 y 4.

Supongamos que ahora desea ver esos elementos con etiquetas de índice 1 y 3. Esta vez, utiliza el método .filter() del DataFrame:

>>> all_beach_boys.filter(items=[1, 3], axis="index")
Traceback (most recent call last):
  ...
ValueError: cannot reindex on an axis with duplicate labels

Ha intentado filtrar el DataFrame con etiquetas de índice 1 y 3 pasándolas como una lista al parámetro items de .filtro(). También configuró el parámetro axis en "index" para aplicar el filtro al índice. A pesar de que su código es técnicamente correcto, el resultado es una excepción ValueError debido a las etiquetas duplicadas.

En este momento, probablemente te sientas un poco muñecado con todos estos contratiempos. Es hora de volver a subirte a tu tablero y resolver los problemas:

Vea si puede corregir este código para que tanto .loc[] como .iloc[] produzcan los mismos resultados, y así .filter() funciona como se esperaba cuando se aplica a all_beach_boys. Además, asegúrese de que se haya eliminado el índice antiguo problemático:

>>> all_beach_boys.loc[[3]]
  first_name last_name instrument date_of_birth
3    Blondie   Chaplin     Guitar   07-Jul-1951

>>> all_beach_boys.iloc[[3]]
  first_name last_name instrument date_of_birth
3    Blondie   Chaplin     Guitar   07-Jul-1951

>>> all_beach_boys.filter(items=[1, 3], axis="index")
  first_name last_name instrument date_of_birth
1       Carl    Wilson     Guitar   21-Dec-1946
3    Blondie   Chaplin     Guitar   07-Jul-1951

Bien hecho. ¡Todo funciona!

Ahora supongamos que desea promover una columna existente a un índice. ¿Es esto posible? Es hora de dejar caer, coger una ola y ver.

Utilice una columna existente como índice

Si bien el índice numérico secuencial predeterminado proporciona un acceso único a las filas dentro de su DataFrame, es poco probable que tenga algún significado inherente. Por ejemplo, los números asignados a cada fila de los DataFrames que ha utilizado hasta este momento no tienen significado en relación con los datos que están indexando.

En el DataFrame leído desde band_members.csv, el miembro de la banda Brian Wilson tiene un valor de índice de 0 simplemente porque aparece primero en el archivo. Esto no tiene ningún significado inherente, aunque puede ofenderte si eres un fan y crees que él debería ser el número 1.

Si bien el concepto de utilizar un índice secuencial no relacionado le resultará familiar si ha trabajado con claves en una base de datos relacional, es posible que desee algo más significativo en sus DataFrames.

Si desea etiquetas de índice más fáciles de usar, puede utilizar una columna existente y promoverla en el índice. Para hacer esto, utiliza el método .set_index(). Aunque puede promocionar cualquier columna existente para que se convierta en índice, tenga en cuenta que, a menos que la columna deseada contenga valores únicos, seguirá teniendo los mismos problemas con los duplicados que vio anteriormente.

Supongamos que desea restablecer su índice para que contenga las etiquetas first_name. Podrías hacer esto como se muestra aquí:

>>> beach_boys = pd.read_csv(
...     "band_members.csv"
... ).convert_dtypes(dtype_backend="pyarrow")

>>> (
...     beach_boys
...     .set_index("first_name")
...     .loc[["Brian", "Carl"]]
... )
           last_name instrument date_of_birth
first_name
Brian         Wilson       Bass   20-Jun-1942
Carl          Wilson     Guitar   21-Dec-1946

Cuando llamas a .set_index() en beach_boys y pasas "first_name", esta columna se promueve al índice. Luego puedes usar .loc[] para seleccionar una o más filas usando los nombres de los músicos que te interesan.

En algunos casos, es posible que desee restablecer su índice para que sus valores existentes sean más significativos para los datos que están indexando. Si bien no puedes usar .reset_index() para esto, puedes aplicar algo más adecuado al atributo .index del DataFrame.

Un ejemplo común es el uso de identificadores de empleados en lugar de números enteros secuenciales simples. El siguiente código actualiza el índice secuencial existente con más valores contextuales:

>>> beach_boys.index = [f"Employee_{x + 1}" for x in range(len(beach_boys))]

>>> beach_boys
           first_name last_name instrument date_of_birth
Employee_1      Brian    Wilson       Bass   20-Jun-1942
Employee_2       Mike      Love  Saxophone   15-Mar-1941
Employee_3         Al   Jardine     Guitar   03-Sep-1942
Employee_4      Bruce  Johnston       Bass   27-Jun-1942
Employee_5       Carl    Wilson     Guitar   21-Dec-1946
Employee_6     Dennis    Wilson      Drums   04-Dec-1944
Employee_7      David     Marks     Guitar   22-Aug-1948
Employee_8      Ricky    Fataar      Drums   05-Sep-1952
Employee_9    Blondie   Chaplin     Guitar   07-Jul-1951

En este código, utilizó una lista por comprensión para crear una lista de cadenas que contienen ["Employee_1", "Employee_2", ...]. Luego, esto se asigna al atributo .index de beach_boys.

Ahora que tiene un índice más significativo, puede usarlo de la misma manera que usó el índice numérico predeterminado. Por ejemplo, puede seleccionar filas por sus nuevos valores Employee_:

>>> beach_boys.loc[["Employee_4"]]
           first_name last_name instrument date_of_birth
Employee_4      Bruce  Johnston       Bass   27-Jun-1942

En el código anterior, utilizó .loc[] para seleccionar el registro de Employee_4.

Ahora un poco de alucinación. ¿No sería bueno si pudieras hacer esto?

Utilizando el marco de datos beach_boys original leído desde band_members.csv, cree un índice que consta de los nombres de usuario del personal en el formato . Su resultado final debería verse así:

>>> beach_boys
          first_name last_name instrument date_of_birth
WilsonB        Brian    Wilson       Bass   20-Jun-1942
LoveM           Mike      Love  Saxophone   15-Mar-1941
JardineA          Al   Jardine     Guitar   03-Sep-1942
JohnstonB      Bruce  Johnston       Bass   27-Jun-1942
WilsonC         Carl    Wilson     Guitar   21-Dec-1946
WilsonD       Dennis    Wilson      Drums   04-Dec-1944
MarksD         David     Marks     Guitar   22-Aug-1948
FataarR        Ricky    Fataar      Drums   05-Sep-1952
ChaplinB     Blondie   Chaplin     Guitar   07-Jul-1951

Como puede ver, el índice ahora contiene un formato de nombre de usuario común, lo que facilitará la selección de usuarios por sus nombres de usuario.

A continuación, adquirirás algo de experiencia surf en tándem. Es hora de utilizar no uno, sino dos DataFrames juntos.

Alinear índices de varios marcos de datos

Una de las grandes características de trabajar con pandas DataFrames es que puede utilizar los operadores aritméticos básicos para sumar sus datos. Desafortunadamente, sólo se le permitirá esta comodidad si sus índices se alinean. De lo contrario, tendrá problemas.

Suponga que está analizando las ventas semanales de discos de una tienda de discos. Los datos de ventas de dos semanas se almacenan dentro de dos archivos CSV denominados week1_record_sales.csv y week2_record_sales.csv. A modo de demostración, ambos archivos contienen datos de ventas idénticos pero sus índices son diferentes:

>>> week1_sales = pd.read_csv(
...     "week1_record_sales.csv"
... ).set_index("index")

>>> week2_sales = pd.read_csv(
...     "week2_record_sales.csv"
... ).set_index("index")

>>> week1_sales
       day  sales
index
0      Mon    100
1      Tue    150
2      Wed    200
3      Thu    250
4      Fri    300

>>> week2_sales
       day  sales
index
1      Mon    100
2      Tue    150
3      Wed    200
4      Thu    250
5      Fri    300

Cada archivo se lee en un DataFrame y contiene información de ventas diarias. Cada fila se identifica por su columna index, que se ha establecido como índice del DataFrame con .set_index().

Suponga que ahora desea encontrar las ventas totales de ambas semanas. Esto debería poder lograrse con poco más que una simple operación aritmética:

>>> week1_sales["sales"] + week2_sales["sales"]
index
0      NaN
1    250.0
2    350.0
3    450.0
4    550.0
5      NaN
Name: sales, dtype: float64

Como puedes ver, algo salió mal. Debido a que ambos DataFrames contienen los mismos datos, es de esperar que las respuestas sean el doble de sus valores originales. En cambio, la primera y la última respuesta son NaN, lo que significa que no se pudo realizar un cálculo aritmético debido a valores faltantes. Además, los resultados restantes son incorrectos.

Ambos problemas fueron causados por índices no coincidentes. Los valores NaN han aparecido porque ni el índice 0 ni el índice 5 aparecen en ambos DataFrames. Los cálculos son incorrectos porque, por ejemplo, la cifra de ventas del miércoles de 200 está indexada como 2 en su primer DataFrame, mientras que el índice 2 se refiere a las ventas del martes de 150 en su segundo DataFrame. Cuando los agregas, el resultado no tiene sentido.

También puede fusionar dos DataFrames de la misma manera que se pueden fusionar tablas de bases de datos relacionales. Esto le permite ver datos coincidentes de ambos DataFrames en el mismo lugar. Nuevamente, si se une a un índice, cada valor de índice debe hacer referencia a los datos relacionados en ambos DataFrames.

Por ejemplo, supongamos que desea ver todos los datos de ambas semanas de ventas. Para hacer esto, puede usar el método .merge() del DataFrame:

>>> week1_sales.merge(week2_sales, left_index=True, right_index=True)
      day_x  sales_x day_y  sales_y
index
1       Tue      150   Mon      100
2       Wed      200   Tue      150
3       Thu      250   Wed      200
4       Fri      300   Thu      250

Inmediatamente puedes ver algunos problemas. Ni los registros con índice 0 ni el índice 5 se ven por ningún lado. Las cifras diarias tampoco coinciden.

Aquí, ha realizado una unión interna de ambos DataFrames, lo que significa que solo se fusionarán los registros cuyos valores de índice aparezcan en ambos DataFrames. Debido a que los valores de índice 0 y 5 no aparecen en ambos, no se incluyen en la combinación. Los días no coinciden porque el mismo índice hace referencia a días diferentes en cada DataFrame.

Para solucionar ambos problemas, debe asegurarse de que ambos DataFrames estén usando el mismo índice. Una forma sería restablecer el índice de week2_sales a su valor predeterminado. Esto coincidirá con el usado por week1_sales, pero solo porque los datos diarios para ambos DataFrames ya están en el mismo orden:

>>> week2_sales = week2_sales.reset_index(drop=True)

Como antes, para restablecer el índice a su valor predeterminado, use .reset_index() y pase True a su parámetro drop para eliminar el problema. índice original. Ahora, cuando ejecutas los dos fragmentos de código anteriores, los resultados son mucho más aceptables:

>>> week1_sales["sales"] + week2_sales["sales"]
index
0    200
1    300
2    400
3    500
4    600
Name: sales, dtype: int64

>>> week1_sales.merge(week2_sales, left_index=True, right_index=True)
      day_x  sales_x day_y  sales_y
index
0       Mon      100   Mon      100
1       Tue      150   Tue      150
2       Wed      200   Wed      200
3       Thu      250   Thu      250
4       Fri      300   Fri      300

Como puedes ver, ahora todo coincide y no falta nada. Alinear los índices ha resuelto ambos problemas de una sola vez. Sin embargo, este ejemplo solo funcionó porque, para empezar, las filas dentro de los DataFrames estaban en el orden correcto. Este no será siempre el caso.

Esta vez vas a pensar lateralmente. Así que dale a tu cerebro un Wipeout y mira si puedes resolver este ejercicio:

Supongamos que está satisfecho con el índice de week2_sales, pero no con el del week1_sales DataFrame. Vea si puede utilizar una de las técnicas que aprendió anteriormente para aplicar el índice de week2_sales al de week1_sales. No olvide asegurarse de que tanto la adición como .merge() sigan produciendo el resultado correcto.

Hasta ahora, ha fusionado los DataFrames en índices numéricos. ¿Se te ocurre una alternativa mejor que funcione incluso si ambos DataFrames originales tuvieran sus filas en un orden diferente? Nuevamente, asegúrese de que tanto la suma como .merge() produzcan el resultado correcto.

Recuerde, siempre puede echar un vistazo a la solución en los materiales descargados.

Para completar su experiencia de aprendizaje, terminará aprendiendo cómo restablecer índices multinivel en DataFrames. No es algo que los surfistas hagan normalmente, a menos que sean Pythonistas como tú.

Restablecer índices múltiples

Cada uno de los DataFrames con los que ha estado trabajando hasta ahora consta de objetos Index de una sola columna. Los DataFrames también admiten objetos MultiIndex, que proporcionan índices jerárquicos o de varios niveles para sus DataFrames.

En esta sección, empiezas a despertarte de tu California Dreaming con los Beach Boys y decides desayunar. Utilizarás el archivo cereals.csv para ayudarte a decidir qué cereal comer. Este archivo contiene datos sobre varios cereales para el desayuno populares de una variedad de fabricantes. Los datos originales provienen de Kaggle y están disponibles gratuitamente bajo la licencia Creative Commons. Aquí, estás usando una versión reducida.

Lo primero que deberá hacer es leer los datos de los cereales en un DataFrame:

>>> cereals = pd.read_csv("cereals.csv").convert_dtypes(
...     dtype_backend="pyarrow"
... )
>>> cereals.head()
                        name    manufacturer  type  fiber
0                  100% Bran         Nabisco  Cold   10.0
1          100% Natural Bran     Quaker Oats  Cold    2.0
2                   All-Bran        Kelloggs  Cold    9.0
3  All-Bran with Extra Fiber        Kelloggs  Cold   14.0
4             Almond Delight  Ralston Purina  Cold    1.0

Como puedes ver, el archivo contiene detalles de diferentes cereales para el desayuno. Cuando llamas al método .head() del DataFrame, ves los primeros cinco registros que revelan el nombre y el fabricante del cereal. También podrás ver su tipo, que te indica si el cereal se debe consumir frío o caliente, así como su contenido en fibra.

No es sorprendente que este DataFrame tenga un índice simple. Una forma rápida de crear un MultiIndex es crear una tabla dinámica a partir de él:

>>> cereals.pivot_table(
...     values="fiber",
...     index=["manufacturer", "type"],
...     aggfunc="mean",
... )
                                     fiber
manufacturer                type
American Home Food Products Hot        0.0
General Mills               Cold  1.272727
Kelloggs                    Cold   2.73913
Nabisco                     Cold       4.6
                            Hot        1.0
Post                        Cold  2.777778
Quaker Oats                 Cold  1.142857
                            Hot        2.7
Ralston Purina              Cold     1.875

Esta tabla dinámica, que en realidad es otro DataFrame, analiza los datos sin procesar calculando el contenido promedio de fibra para cada tipo de cereal para cada fabricante. El índice de este DataFrame es un poco diferente de lo que estás acostumbrado a ver:

>>> cereals.pivot_table(
...     values="fiber",
...     index=["manufacturer", "type"],
...     aggfunc="mean",
... ).index
MultiIndex([('American Home Food Products',  'Hot'),
            (              'General Mills', 'Cold'),
            (                   'Kelloggs', 'Cold'),
            (                    'Nabisco', 'Cold'),
            (                    'Nabisco',  'Hot'),
            (                       'Post', 'Cold'),
            (                'Quaker Oats', 'Cold'),
            (                'Quaker Oats',  'Hot'),
            (             'Ralston Purina', 'Cold')],
           names=['manufacturer', 'type'])

El MultiIndex en esta tabla dinámica consta de columnas fabricante y tipo. En lugar de las simples columnas individuales que ha visto hasta ahora, ahora tiene una estructura de varios niveles más compleja.

En este ejemplo, ha creado un MultiIndex que consta de dos niveles. Estos se definen pasando "manufacturer" y "type" al parámetro index de .pivot_table().

Dentro del objeto MultiIndex, fabricante se conoce como nivel 0, mientras que tipo es nivel 1 . . Estos números de nivel son importantes si necesita restablecer el índice porque le permiten hacerlo en un nivel específico, o incluso restablecerlo por completo.

Supongamos que desea restablecer solo el nivel 1, correspondiente a type, lo que lo relega a una columna separada antes de eliminarlo por completo:

>>> cereals = pd.read_csv("cereals.csv").convert_dtypes(dtype_backend="pyarrow")
>>> cereals.pivot_table(
...     values="fiber",
...     index=["manufacturer", "type"],
...     aggfunc="mean"
... ).reset_index(level=1, drop=True)

>>> cereals
                                fiber
manufacturer
American Home Food Products       0.0
General Mills                1.272727
Kelloggs                      2.73913
Nabisco                           4.6
Nabisco                           1.0
Post                         2.777778
Quaker Oats                  1.142857
Quaker Oats                       2.7
Ralston Purina                  1.875

Al pasar level=1 y drop=True a .reset_index(), eliminas los detalles de type, conservando sólo la información del fabricante como un simple Índice.

Tenga cuidado al hacer esto, porque ahora ha creado valores de índice duplicados con todos los problemas que vio anteriormente. Además, sus datos ahora han perdido parte de su significado. Por ejemplo, existe confusión sobre lo que le muestran las etiquetas Nabisco y Quaker Oats. Ya no sabes cuál se refiere a los cereales calientes y cuál a los fríos.

Tenga en cuenta que restablecer parte de un MultiIndex puede tener efectos secundarios indeseables que no siempre son obvios.

Es hora de Coger una ola y realizar un Surfin’ Safari en tu penúltimo desafío:

Usando el código anterior como guía, vea si puede producir este resultado exacto para aclarar la confusión de Nabisco y Quaker Oats:

>>> cereals
                     manufacturer     fiber
type
Cold                General Mills  1.272727
Cold                     Kelloggs   2.73913
Cold                      Nabisco       4.6
Cold                         Post  2.777778
Cold                  Quaker Oats  1.142857
Cold               Ralston Purina     1.875
Hot   American Home Food Products       0.0
Hot                       Nabisco       1.0
Hot                   Quaker Oats       2.7

La información de tipo forma el índice, mientras que la información de fabricante está nuevamente en una columna.

A veces, es mejor restablecer todos los niveles de un MultiIndex pero conservar todos los datos. Cuando aplica .reset_index() a un MultiIndex usando sus parámetros predeterminados, reemplazará el índice completo con una versión predeterminada simple y creará columnas adicionales a partir del índice original dentro. su marco de datos:

>>> cereals.pivot_table(
...     values="fiber",
...     index=["manufacturer", "type"],
...     aggfunc="mean",
... ).reset_index()
                  manufacturer  type     fiber
0  American Home Food Products   Hot       0.0
1                General Mills  Cold  1.272727
2                     Kelloggs  Cold   2.73913
3                      Nabisco  Cold       4.6
4                      Nabisco   Hot       1.0
5                         Post  Cold  2.777778
6                  Quaker Oats  Cold  1.142857
7                  Quaker Oats   Hot       2.7
8               Ralston Purina  Cold     1.875

Esta vez, su DataFrame tiene un índice predeterminado aplicado, pero también tiene nuevas columnas manufacturer y type, así como la columna agregada fiber. datos. Lo más importante es que los datos no han perdido nada de su significado.

Este desafío final pondrá a prueba esas buenas vibraciones que ahora tienes sobre tu capacidad para trabajar con índices de DataFrame.

Vea si puede resolver los efectos secundarios indeseables de su tabla dinámica original aplanando el MultiIndex. Quizás se vea así:

>>> cereals
                                       fiber
(American Home Food Products, Hot)       0.0
(General Mills, Cold)               1.272727
(Kelloggs, Cold)                     2.73913
(Nabisco, Cold)                          4.6
(Nabisco, Hot)                           1.0
(Post, Cold)                        2.777778
(Quaker Oats, Cold)                 1.142857
(Quaker Oats, Hot)                       2.7
(Ralston Purina, Cold)                 1.875

El índice ahora consta de un nivel en lugar de dos, pero cada nivel es una tupla.

¡Eso es todo! Debería estar emocionado de saber que ahora tiene un conocimiento completo de cómo restablecer el índice en sus DataFrames utilizando varias técnicas. También recibió una lección adicional sobre cómo incorporar títulos de canciones de Beach Boys y referencias cursis de navegación en un tutorial de Python. Un original verdaderamente rad de tus amigos de Real Python.

Conclusión

En este tutorial, aprendió que si bien el método .reset_index() es la forma más personalizable de restablecer un índice, no es la opción más rápida. Sin embargo, es útil cuando trabaja con restablecimientos de MultiIndex.

También aprendió que aplicar directamente el índice a la propiedad .index del DataFrame es la forma más rápida de restablecer un índice y que cambia el DataFrame original en el proceso. Además, descubrió cómo el método .set_axis() le permite restablecer y volver a etiquetar su índice si así lo desea.

Felicitaciones por completar este tutorial y disfrute aplicando estas nuevas habilidades para preparar mejor sus DataFrames para el análisis. ¡Feliz surf!