Dataframes en Pandas

En este tema vamos a hablar de los dataframes en pandas, probablemente la estructura que más emplearemos. Un dataframe es asimilable a una tabla, es una estructura bidimensional de filas y columnas.

En la practica, cargaremos nuestros datos desde un fichero o una base de datos en un dataframe. Y esta será la estructura de datos que emplearemos en nuestros programas para trabajar con los datos. Cuando hallamos finalizado las operaciones que queramos con los datos, guardaremos el dataframe en algún sistema de persistencia de datos: un fichero o una base de datos.

El objeto Dataframe

El objeto dataframe no es más que la instancia de la clase del mismo nombre que provee la libreria pandas. Este objeto pretende representar una tabla con sus filas y columnas. Y como todo objeto, tiene sus atributos y sus métodos. Si tienes dudas sobre estos temas o necesitas recordarlos, échale un vistazo rápido al tema de Clases y Objetos en Python

Los principales atributos de un objeto dataframe son:

  • index: Devuelve los índices del DataFrame en un objeto Index.
  • columns: Devuelve los nombres de las columnas en un objeto Index.
  • shape: Devuelve la tupla (número de filas, número de columnas).
  • dtypes: Muestra los tipos de datos de cada columna.
  • values: Devuelve los datos como un array de NumPy.

El constructor de esta clase lo veremos en detalle en el siguiente apartado, pero ya podeis imaginaros que como poco habrá que pasarle los datos, también es habitual pasarle los nombres de las columnas.

En cuanto a los métodos de la clase, a continuación te dejo una lista de alguno de los más habituales. Voy a distinguir entre los métodos de instancia y los de clase, recuerda que los primeros los llamas a traves del objeto (la instancia de la clase) y los segundos los tienes que llamar a traves del nombre de la libreria: pandas o su alias más habitual: pd, si así lo definiste en la importación. Todos ellos los iremos viendo según vayamos trabajemos con dataframes.

Los principales métodos de instancia son:

  • df.head(n): Muestra las primeras n filas del DataFrame (por defecto 5).
  • df.tail(n): Muestra las últimas n filas.
  • df.info(): Muestra información general sobre el DataFrame (tipo de datos, valores nulos, memoria utilizada).
  • df.describe(): Genera estadísticas descriptivas para las columnas numéricas.
  • df.loc[filas, columnas]: Selecciona filas y columnas por etiquetas.
  • df.iloc[filas, columnas]: Selecciona filas y columnas por posición numérica.
  • df.drop(columns=[‘col1’]): Elimina las columnas indicadas en el parámetro columns.
  • df.rename(columns={‘col1’: ‘nuevo_nombre’}): Renombra las columnas de acuerdo con la información en el diccionario que se pasa en el parámetro columns. Las claves identifican los nombres de las columnas actuales y los valores los nuevos nombres a dar a dichas columnas.
  • df.sort_values(by=’columna’, ascending=True): Ordena el DataFrame por las columnas que se indican en el parámetro by, en el sentido que se indica en el parámetro ascending.
  • df.isnull(): Devuelve un DataFrame con True en los registros con algún valor nulo.
  • df.dropna(): Elimina filas con algún valor nulo.
  • df.fillna(valor): Rellena valores nulos con un valor específico.
  • df.groupby(‘columna’): Agrupa datos por la columna indicada.
  • df.to_csv() y df.to_excel(): Guarda el DataFrame en un archivo y Excel, respectivamente.

Y los principales métodos de clase:

  • pd.concat([df1, df2], axis=0): Une DataFrames por filas o columnas, según se indique en el parámetro axis
  • pd.read_csv() y pd.read_excel(): Carga como DataFrame un archivo csv y un Excel, respectivamente.

De todos modos, iremos viendolos con ejemplos de código según avancemos en el tema.

Creación de dataframes

Lógicamente, lo primero que tendremos que hacer será crear un dataframe para poder trabajar con él. Y básicamente tenemos dos posibilidades de hacerlo: a partir de datos guardados (ficheros o bases de datos) o a partir de datos de nuestro programa. Primero vamos a ver como generar estas estructuras con datos de nuestros programas, y luego veremos como hacerlo a partir de datos en ficheros.

Creando dataframes a partir de listas

Podemos crear dataframes a partir de listas de datos, sencillamente pasando las listas como los valores a guardar en el dataframe

import pandas as pd
alquiler=[700,700,700]
calefaccion=[45,56,34]
valores=[alquiler,calefaccion]
df=pd.DataFrame(valores)
print(df)

Puede observarse que se emplea el método de clase DataFrame para crear el objeto df. El resultado de ejecutar el código anterior sería:

     0    1    2
0  700  700  700
1   45   56   34

Se observa que tanto las columnas como las filas las numera de manera secuencial empezando en cero. Pero podemos poner nombres tanto a las columnas como a las filas empleando los parámetros columns y index, respectivamente.

import pandas as pd
meses=["enero","febrero","marzo"]
gastos=["Alquiler","Calefacción"]
alquiler=[700,700,700]
calefaccion=[45,56,34]
valores=[alquiler,calefaccion]
df=pd.DataFrame(valores,columns=meses,index=gastos)
print(df)

El resultado de ejecutar el programa anterior es:

             enero  febrero  marzo
Alquiler       700      700    700
Calefacción     45       56     34

Creando dataframes a partir de diccionarios

Otra forma muy socorrida de crear dataframes es a partir de los datos de diccionarios. Un diccionario equivaldría a una fila, las claves se asimilan a las columnas y los valores del diccionario a los valores en la fila del dataframe. Los valores que se pasarían al método DataFrame sería una lista de diccionarios, uno por cada línea. Por ejemplo, el dataframe anterior se definiría de la siguiente forma:

import pandas as pd
gastos=["Alquiler","Calefacción"]
alquiler={"enero":700,"febrero":700,"marzo":700}
calefaccion={"enero":45,"febrero":56,"marzo":34}
valores=[alquiler,calefaccion]
df=pd.DataFrame(valores,index=gastos)
print(df)

Fijate que para definir los títulos de las filas sigo manteniendo la lista de gastos que la paso en el parámetro index, pero sin embargo, esta vez no paso nada en el parámetro columns. El resultado del programa anterior es el mismo que cuando creabamos el dataframe a partir de listas:

             enero  febrero  marzo
Alquiler       700      700    700
Calefacción     45       56     34

La ventaja de usar diccionarios es que mediante la clave estamos indicando la columna en la que hay que colocar el dato, mientras que si empleamos listas los datos se van colocando por orden secuencial.

Veamoslo en nuestro ejemplo anterior. Supongamos que la calefacción se paga cada dos meses y por tanto en febrero no se paga calefacción. Si emplearamos listas para generar el dataframe tendríamos el siguiente código:

import pandas as pd
meses=["enero","febrero","marzo"]
gastos=["Alquiler","Calefacción"]
alquiler=[700,700,700]
calefaccion=[45,34]
valores=[alquiler,calefaccion]
df=pd.DataFrame(valores,columns=meses,index=gastos)
print(df)

El código nos va a correr sin errores, pero si vemos el resultado del mismo, se aprecia que nos coloca los valores de calefacción de forma secuencial, rellenando las columnas por orden y dejando vacía la última columna: marzo

             enero  febrero  marzo
Alquiler       700      700  700.0
Calefacción     45       34    NaN

Lo cual es incorrecto, ya que la columna vacia debe ser febrero. Este problema se soluciona si usamos diccionarios, porque la clave del diccionario ya indica en que columna tiene que ir el valor. El programa anterior con diccionarios sería:

import pandas as pd
gastos=["Alquiler","Calefacción"]
alquiler={"enero":700,"febrero":700,"marzo":700}
calefaccion={"enero":45,"marzo":34}
valores=[alquiler,calefaccion]
df=pd.DataFrame(valores,index=gastos)
print(df)

Y el resultado del mismo es:

             enero  febrero  marzo
Alquiler       700    700.0    700
Calefacción     45      NaN     34

Vemos que nos coloca cada dato en su columna correspondiente dejando vacio el dato de gasto de calefacción en febrero. (NaN (Not a number): es un valor especial, heredado de numpy, que representa datos faltantes o desconocidos)

Importar datos en un dataframe

Normalmente los datos con los que queremos trabajar estarán en algún soporte con persistencia, tipicamente un fichero o base de datos.

Para las bases de datos relacionales, nos traeríamos resultados de consultas que normalmente los tendremos en duplas. Una vez convertidas a listas podrían emplearse para generar dataframes y trabajar con los datos en esta estructura. Puedes repasar como trabajar con bases de datos en el tema correspondiente.

Para cargar datos desde un fichero, pandas proveee varios métodos:

  • read_csv: Carga ficheros csv (separados por comas).
  • read_excel: Ficheros Excel
  • read_json: Ficheros formato JSON
  • read_html: Ficheros formato HTML
  • read_sas: Ficheros procedentes de SAS (Sistema estadístico)
  • read_parquet: Ficheros formato parquet (formato open-source para la serialización de datos)

Lógicamente, a todos los métodos hay que indicarles el fichero del que se quieren cargar los datos. Esto es, la ruta completa incluido el nombre y extensión del fichero.

Por ejemplo, si quisieramos cargar los datos del naufragio del Titanic y los tenemos en un fichero excel en la carpeta «data» de nuestro disco duro, usariamos el siguiente código:

import pandas as pd
ruta="c:\\data\\titanic.xlsx"
df_excel=pd.read_excel(ruta)
print(df_excel)

En este ejemplo, he empleado el doble \\ para indicar la ruta. El primer \ equivale a un caracter de escape con lo que me queda un único \ en la ruta.

En la mayoria de los sistemas nos va admitir una única barra inclinada en el otro sentido, es decir, hacia la derecha:

ruta="c:/data/titanic.xlsx"

En cualquier caso, si te quieres curar en salud, lo mejor es usar una cadena cruda, que lo indicas con una r delante:

ruta = r"c:\data\titanic.xlsx"

Y una opción más «actual» es usar pathlib.Path, e indicas la ruta de carpetas y el fichero por separado:

from pathlib import Path
ruta = Path("c:/data") / "titanic.xlsx"

Los principales parámetros del método read_excel() son:

  • io: Ruta del archivo de Excel o un objeto de tipo ExcelFile.
  • sheet_name: Nombre o número de la hoja a leer (por defecto 0, la primera hoja). Con el valor None se obtienen todas las hojas en un diccionario.
  • usecols: Lista de nombres de columnas o rango de columnas a importar.
  • skiprows: Número de filas a omitir al inicio del archivo o lista de filas a ignorar.
  • nrows: Número de filas a leer después de skiprows.
  • dtype: Diccionario con tipos de datos para columnas.
  • na_values: Valores a interpretar como NaN.
  • header: Número de fila que contiene los nombres de las columnas (por defecto 0).
  • index_col: Número o lista de columnas a usar como índice.
  • engine: Motor de lectura («openpyxl» para .xlsx, «xlrd» para .xls).

Y los principales parámetros del método read_csv():

  • filepath_or_buffer: Ruta del archivo csv o una URL de donde leer los datos.
    • sep: Delimitador usado en el archivo (por defecto «,»)
    • header: Fila donde se encuentran los nombres de las columnas (0 por defecto, None si no hay encabezados).
    • names: Lista de nombres de columnas si no hay encabezado en el archivo.
    • index_col: Número o lista de columnas a usar como índice ( None para sin índice).
    • usecols: Lista de columnas específicas a leer.
    • skiprows: Número de filas a omitir al inicio o lista de filas a ignorar.
    • nrows: Número de filas a leer después de skiprows.
    • na_values: Lista de valores a interpretar como NaN.
    • encoding: Codificación del archivo (ejemplo: «utf-8», «latin1»).

Guardar datos de un dataframe

Una vez hayamos trabajado con los datos del dataframe, es posible que queramos guardar los resultados para usarlos más adelante. Pandas provee una serie de métodos que nos permiten guardar los datos en un fichero:

  • to_csv: Ficheros csv (separados por comas)
  • to_excel: Ficheros Excel
  • to_json: Ficheros formato JSON
  • to_html: Ficheros formato HTML
  • to_sas: Ficheros procedentes de SAS (Sistema estadístico)
  • to_parquet: Ficheros formato parquet (formato open-source para la serialización de datos)

Todos estos métodos requieren que se les pase la ruta y el nombre del fichero.

Cada método tiene parámetros específicos. Aquí comentaré los que probablemente sean los dos más habituales: to_excel() y to_csv()

Método to_excel()

Para emplear el método to_excel() y poder guardar los datos en un fichero excel, se necesita tener instalada la librería openpyxl. Ojo, cuando instalamos pandas no se instala esta dependencia con lo que hay que hacerlo exproceso:

pip install openpyxl

Los principales parámetros del método to_excel() son:

  • excel_writer: Ruta del archivo de salida.
  • sheet_name: Nombre de la hoja donde se guardarán los datos (por defecto «Sheet1»).
  • index: Booleano que indica si se debe incluir el índice en el archivo (por defecto True).
  • header: Booleano o lista de nombres de columnas. False indica que no se escriben los encabezados.
  • startrow / startcol: Especifican la fila y columna inicial donde se escribirán los datos en la hoja de Excel.
  • engine: Especifica el motor a utilizar (‘openpyxl’ para .xlsx o ‘xlwt’ para .xls).
  • freeze_panes: Permite congelar filas o columnas, útil para mejorar la visualización.

Por ejemplo, el siguiente programa guarda el dataframe de gastos con el que veniamos trabajando en un archivo de formato excel.

import pandas as pd
gastos=["Alquiler","Calefacción"]
alquiler={"enero":700,"febrero":700,"marzo":700}
calefaccion={"enero":45,"marzo":34}
valores=[alquiler,calefaccion]
df=pd.DataFrame(valores,index=gastos)
print("guardando datos en un excel")
df.to_excel("gastos.xlsx")

Método to_csv()

Otro formato muy habitual es el formato csv, donde los datos se separan por un separador que se indica en el parámetro sep. Si no se indica el separador, el valor por defecto es la coma.

Los principales parámetros del método to_csv() son:

  • path_or_buf: Ruta del archivo de salida o un objeto buffer donde escribir los datos.
  • sep: Separador de los valores en el archivo (por defecto «,»; puede ser «;», «\t», etc.).
  • index: Booleano que indica si se debe incluir el índice en el archivo (por defecto True).
  • header: Booleano o lista de nombres de columnas. False indica que no se escriben los encabezados.
  • encoding: Codificación del archivo («utf-8» o «latin1»).
  • columns: Lista de columnas específicas a exportar.
  • line_terminator: Carácter usado al final de cada línea (por defecto «\n»).

Por ejemplo, el código siguiente guarda en un fichero csv los datos del dataframe con el que venimos trabajando.

import pandas as pd
gastos=["Alquiler","Calefacción"]
alquiler={"enero":700,"febrero":700,"marzo":700}
calefaccion={"enero":45,"marzo":34}
valores=[alquiler,calefaccion]
df=pd.DataFrame(valores,index=gastos)
print("guardando datos en un csv")
df.to_csv("gastos.csv")

NOTA:

Este post es parte de la colección “Python”. Puedes ver el índice de esta colección aquí.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.