Guía práctica para análisis exploratorio de datos con Pandas
En la publicación anterior sobre análisis de datos mencioné el análisis exploratorio de datos, el cual nos permitirá definir si los datos que tenemos son suficientes y son los que necesitamos para cumplir con el objetivo planteado. Además, en este análisis podemos identificar si en nuestros datos hay valores nulos, atípicos, los tipos de variables, la distribución de los datos y comportamiento general de la información recopilada.
Python ha sido uno de los lenguajes de programación más utilizados por la comunidad de científicos de datos, tanto para la preparación de datos como para la implementación de modelos de machine learning y deep learning. Este lenguaje nos permite realizar un análisis exploratorio de datos mediante una de sus librerías, Pandas.
Pandas es una librería de código abierto de Python, basada en Numpy (librería para manejo de arrays) y Matplotlib (librería para visualización de datos).
Pandas es una librería especializada en el manejo y análisis de estructuras de datos.
Dato: El nombre de esta librería viene de la unión de las palabras Panel - Data.
Si quieres saber más acerca de esta librería recomiendo consultar en la documentación oficial: https://pandas.pydata.org. En esta página podrás encontrar como instalar Pandas y una guía de usuario con ejemplos cortos sobre como usarla.
Pandas nos permite cargar datos, modelarlo, realizar la preparación, manipulación y análisis de los mismos, para ello nos presenta un concepto fundamental para visualizar las estructuras de datos, los DataFrames. Son estructuras de datos etiquetados bidimensionales, es decir, que contienen filas y columnas.
Importar Pandas
Como estándar se importa pandas como pd
import pandas as pd
Leer y guardar archivos CSV
Pandas nos permite leer archivos en formato CSV (archivos separados por comas) y convertirlos a una estructura de datos como DataFrame para trabajar con ellos.
df = pd.read_csv("<dirección donde se encuentra el archivo>")
Asimismo, pandas nos permite almacenar un DataFrame que hayamos creado o que esté modificado y listo para ingresar a un modelo de ML o implementar visualizaciones.
df.to_csv("<ruta donde almacenar el archivo con el nombre finalizando en .csv>")
Pandas también nos permite leer archivos HTML, Json, SQL y Excel.
pd.read_html("<ruta>")
pd.read_json("<ruta>")
pd.read_sql("<ruta>")
pd.read_excel("<ruta>")
Crear un DataFrame
Se pueden crear DataFrame de dos formas:
- A partir de diccionarios de listas.
Para este caso vamos a crear un DataFrame con datos de un supermercado. La clave del diccionario es el nombre de la columna y el valor es una lista donde cada elemento contiene la información de la columna en el DataFrame. Cada valor de las columnas debe estar ingresado en el orden que corresponda para visualizar de manera correcta las filas del DataFrame.
Primero, definimos el diccionario:
dic_to_df = {'Categoria':['Verduras','Lacteos','Carnes frias'],
'Producto':['Pepino','Leche Entera','Salchichas'],
'Precio':[600,2300,4650],
'Fecha':['2021-01-02','2019-01-31','2020-05-25']}
Luego, el diccionario se convierte a DataFrame:
df = pd.DataFrame(dic_to_df)
- A partir de listas de diccionarios.
En este caso cada elemento de la lista es un diccionario que contiene la información de una fila del DataFrame. Las claves serán los nombres de las columnas y los valores tendrán la información que corresponde al producto ingresado.
Primero, creamos la lista de diccionarios con la información de los productos:
list_to_df =[{'Categoria':'Verduras','Producto':'Pepino','Precio':600,'Fecha':'2021-01-02'},
{'Categoria':'Lacteos','Producto':'Leche Entera','Precio':2300, 'Fecha':'2019-01-31'},
{'Categoria':'Carnes Frias','Producto':'Salchichas','Precio':4650, 'Fecha':'2020-05-25'}]
Luego, creamos el DataFrame:
df = pd.DataFrame(list_to_df)
Visualizar un DataFrame
Para visualizar un DataFrame podemos simplemente poner el nombre que le hemos asignado al DataFrame y visualizarlo como en las imágenes anteriores. Esta es una buena opción cuando tenemos pocos datos, pero cuando la cantidad de datos aumenta se hace tediosa la visualización. Pandas nos presenta una opción para visualizar algunas filas del DataFrame y con ello hacernos una idea de los datos que vamos a preparar.
df.head()
Con este método de Pandas podemos visualizar las cinco primeras filas del DataFrame. También podemos indicar dentro del paréntesis cuantas filas del DataFrame queremos ver:
df.head(10)
Con la línea de código anterior podremos visualizar las 10 primeras filas del DataFrame.
df.tail()
El método anterior nos permite visualizar las últimas filas del DataFrame. Al igual que .head() le podemos indicar el numero de filas que queremos visualizar.
Explorar el DataFrame
Para explorar el DataFrame e identificar datos importantes del DataFrame con el que vamos a trabajar podemos usar los siguientes métodos, también mencionados en la publicación anterior Análisis de datos.
- Información de DataFrame por cada columna, con cantidad de valores nulos y tipos de datos:
df.info()
- Algunos datos estadísticos del DataFrame para las columnas numéricas: Total de datos, media, valor mínimo y máximo, cuartiles.
df.describe()
Clasificación y subconjuntos de datos
Podemos ordenar los valores de un DataFrame por orden alfabético, de manera descendente y ascendente.
df.sort_values('<nombreColumna>', ascending = False)
En este método, ascending viene por defecto con el valor True, es decir que ordena los datos de forma ascendente.
Se pueden ordenar por mas de una columna, para ello se ingresan los nombres de las columnas como una lista, al igual que los valores que tomará ascending.
df.sort_values(['<nombreColumna1, nombreColumna2 >'], ascending = [False, True])
Para un subconjunto de datos de un DataFrame podemos indicar el nombre de la columna o columnas que queremos visualizar.
df['<nombreColumna>']
df[['<nombreColumna1>','<nombreColumna1>']]
También se pueden visualizar los datos que cumplen una condición definida.
df[df['<nombreColumna>']<Condición>]
En la condición se puede indicar que el valor de esa columna sea mayor, igual, menor o diferente a un valor definido. Incluso se pueden definir varias condiciones haciendo uso de operadores lógicos (and, or).
Finalmente, si queremos columnas que tengan un valor especifico podemos usar el método .isin()
condicion = df['<nombreColumna>'].isin([<Valor o valores>]) df[condicion]
Resumen estadístico
df['<nombreColumna>'].mean() #Media
df['<nombreColumna>'].median() #Mediana
df['<nombreColumna>'].mode() #Moda
df['<nombreColumna>'].min() #Valor mínimo
df['<nombreColumna>'].max() #Valor máximo
df['<nombreColumna>'].var() #Varianza
df['<nombreColumna>'].std() #Desviación estándar
df['<nombreColumna>'].sum() #Suma
df['<nombreColumna>'].quantile() #Cuartiles
Estadísticas acumulativas:
df['<nombreColumna>'].cumsum() #Suma acumulativa
df['<nombreColumna>'].cummin() #Mínimo acumulativo
df['<nombreColumna>'].cummax() #Máximo acumulativo
df['<nombreColumna>'].cumprod() #Producto acumulativo
También podemos usar el metodo .agg() para uno o mas métodos o para aplicar una función previamente definida a los datos.
df['<nombreColumna>'].agg(<funcion>)
Eliminar valores duplicados
Pandas nos permite identificar valores duplicados en el DataFrame y eliminarlos.
df.drop_duplicates(subset="<nombreColumna>",inplace=True)
El parámetro inplace nos permite indicar si queremos que los valores duplicados se eliminen directamente en el DataFrame.
Contar valores del DataFrame
Es útil contar los valores que tenemos en el DataFrame, esta es otra forma de identificar valores duplicados para luego eliminarlos.
df['<nombreColumna>'].value_counts(sort=True)
Valores NaN
Los datos difícilmente están perfectos y listos para realizar su visualización o crear modelos de ML, debemos realizar una limpieza previa. Algo que se suele hacer es identificar los valores NaN (Not a Number) y eliminarlos o usar técnicas para reemplazarlos.
Identificar si nuestro DataFrame tiene valores NaN:
df.isna()#Indica valores booleanos (True o False) por cada elemento
df.isna().any() #Indica valores booleanos por cada columna
df.isna().sum() #Indica valores numéricos por cada columna
Para eliminar los valores NaN:
df.dropna(inplace=True)
Para reemplazarlos por un valor especifico:
df.fillna(<valor>)
Selección de datos
En esta ocasión veremos .iloc[] y .loc[]. Técnicas para seleccionar partes de datos.
.iloc[]: Está basado en posición. El numero indicado al final es excluyente, es decir, si usamos .iloc[1:5] nos muestra los valores desde la posición 1 hasta la 4.
.loc[]: Está basado en etiquetas. Ambos valores indicados están incluidos.
df.iloc[<numeroFila>,<numeroColumna>]df.loc[<indiceInicio>:<indiceFin>]
numeroFila y numeroColumna pueden ser un único numero o se usa la notación inicio:fin (al igual que en .loc).
Group By
Este método nos permite agrupar datos por determinados valores en común para calcular operaciones.
df.groupby("<nombreColumna1>")["<nombreColumna2>"].agg(<[funcion]>)
nombreColumna1: Determina la columna por la cual se van a agrupar los datos
nombreColumna2: Este valor es opcional e indica los valores de otra columna del DataFrame al que le vamos a aplicar las funciones indicadas con .agg().
En el siguiente repositorio podrás encontrar un ejercicio práctico con todos los métodos vistos en esta publicación: https://github.com/lauralpezb/Pandas/blob/master/dataChallenge_pandas.ipynb
Documentación recomendada para Pandas y Python: