¿Te interesa hacer un curso de pandas? Echa un vistazo a nuestro curso Data Manipulation with pandas .
Importación de datos Para empezar a explorar, lo primero es cargar los datos. Seguramente esto ya lo sepas, pero gracias a pandas es muy sencillo: importas el paquete como pd, siguiendo la convención, y usas la función read_csv(), a la que le pasas la URL donde están los datos y el argumento header. Este último te ayuda a asegurarte de que la lectura es correcta: así la primera fila no se interpreta como nombres de columnas del DataFrame.
Además, hay otros argumentos que puedes especificar para garantizar una lectura correcta: por ejemplo, el separador con sep o delimiter, los nombres de columna con names o la columna que se usará como índice de filas del DataFrame resultante con index_col.
Y estos no son ni mucho menos todos los argumentos de read_csv(). Consulta la documentación para verlos en detalle.
# Import the `pandas` library as `pd`
import pandas as pd
# Load in the data with `read_csv()`
digits = pd.read_csv("http://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tra",
header=None)
# Print out `digits`
print(digits)
En este caso usamos read_csv() porque los datos están separados por comas. Si tus archivos usan otro separador, puedes considerar otras funciones para la carga, como read_table(), read_excel(), read_fwf() o read_clipboard, para archivos delimitados en general, ficheros de Excel, datos de ancho fijo y datos copiados al portapapeles, respectivamente.
También puedes usar read_sql() para leer una consulta SQL o una tabla de base de datos en un DataFrame. Para más funciones de entrada/salida, consulta esta sección de la documentación de pandas.
¿Qué es el análisis exploratorio de datos (EDA)? El análisis exploratorio de datos (EDA) sirve, por un lado, para responder preguntas, contrastar hipótesis de negocio y generar nuevas hipótesis para análisis posteriores. Por otro, también puedes usarlo para preparar los datos para el modelado. En ambos casos, la clave es conocer bien tus datos para obtener respuestas o desarrollar intuición a la hora de interpretar resultados de futuros modelos.
Hay muchas formas de lograrlo: obtener una descripción básica, visualizar, identificar patrones, detectar retos de uso de los datos, etc.
Uno de los conceptos que verás a menudo al leer sobre EDA es el data profiling. El data profiling se centra en resumir tu dataset mediante estadísticas descriptivas. Buscas usar distintas medidas para entender mejor el conjunto de datos. Su objetivo es tener una comprensión sólida para, después, empezar a consultar y visualizar los datos de distintas maneras. Eso sí, no significa que no debas iterar: precisamente porque resume el dataset, se usa con frecuencia para evaluar la calidad de los datos. Según el resultado, puedes decidir corregir, descartar o tratarlos de otra forma.
Aprenderás más sobre data profiling en una próxima publicación.
EDA y minería de datos (DM) El EDA se diferencia de la minería de datos, aunque estén muy relacionados, ya que muchas técnicas de EDA se han adoptado en minería de datos. Sus objetivos también son similares: EDA te ayuda a explorar los datos para que destaquen características y relaciones entre variables. En EDA sueles explorar y comparar muchas variables con diversas técnicas para buscar y encontrar patrones sistemáticos. La minería de datos, en cambio, se centra en extraer patrones del dataset. Esos patrones aportan información sobre relaciones entre variables que pueden mejorar la toma de decisiones. En ambos casos, no tienes expectativas a priori o no son completas sobre las relaciones entre variables.
En general, la minería de datos es más aplicada, mientras que EDA se preocupa por la naturaleza básica de los fenómenos subyacentes. Dicho de otro modo, la minería de datos presta relativamente menos atención a identificar relaciones específicas entre variables implicadas. Por eso acepta un enfoque de “caja negra” y usa no solo técnicas de EDA sino también otras como redes neuronales para generar predicciones válidas sin identificar la naturaleza exacta de las relaciones en que se basan.
Descripción básica de los datos Como has visto, el EDA va de conocer tus datos. Uno de los pasos más elementales es obtener una descripción básica. Este término es amplio: puede ser una forma rápida de extraer información sencilla y comprensible para tomar el pulso al dataset.
En esta sección no distinguiremos entre interpretaciones: verás varias formas rápidas de obtener información fácil de entender sobre tu DataFrame.
Describir los datos Por ejemplo, puedes usar describe() para obtener varias estadísticas resumen que excluyen NaN. Considera este ejemplo con el famoso dataset Iris . Los datos ya están cargados en el bloque de DataCamp Light:
Verás que devuelve recuento, media, desviación estándar, valores mínimo y máximo y cuantiles. Hay muchas bibliotecas en Python que proporcionan estas estadísticas (incluida la propia pandas). Esta función es solo una de las formas de obtener esa información.
También conviene dedicar tiempo a profundizar en las estadísticas descriptivas si aún no lo has hecho. Puedes usarlas para empezar a evaluar la calidad de tus datos. Después decidirás si corregir, descartar o tratar los datos de otra manera. Este suele ser el paso de data profiling. Su objetivo en el EDA es entender mejor los elementos y anomalías y ver cómo encajan con la documentación por un lado y con las necesidades del negocio por otro.
Nota : volverás a la etapa de data profiling a medida que avances en tu análisis exploratorio, ya que la calidad de los datos puede verse afectada por los pasos que vayas realizando.
Primeras y últimas filas del DataFrame Ahora que ya tienes una idea general, también conviene mirar los datos de cerca. Con las funciones head() y tail() de pandas puedes ver fácilmente las primeras y últimas líneas del DataFrame, respectivamente.
Inspecciona las primeras y últimas cinco filas del dataset de dígitos escritos a mano con head() y tail() en el bloque de abajo. Ya están cargados para ti:
# Inspect the first 5 rows of `digits`
first = digits._____(5)
# Inspect the last 5 rows
last = digits.____(5)
Verás que el resultado de head() y tail() dice poco si no estás familiarizado con este tipo de datos.
Puede que solo veas filas y columnas con valores numéricos. Lee la descripción del dataset si aún no lo has hecho: te dará información relevante sobre cómo se recogieron los datos y el número de atributos y filas, útil para comprobar si los importaste correctamente.
Vuelve a tu hallazgo inicial: los valores numéricos en las filas. A primera vista puede que no veas ningún problema, ya que los enteros parecen correctos y no levantan sospechas.
Pero, si esto lo hubieras hecho con otro dataset con fechas y horas, por ejemplo, un vistazo rápido podría haberte hecho preguntar: «¿Se ha leído como DateTime?», «¿Cómo lo compruebo?» y «¿Cómo cambio el tipo de datos?».
Estas son preguntas más profundas que abordarás típicamente en el paso de data profiling, que trataremos en otra publicación.
Muestrear los datos Si tu dataset es grande, puedes tomar una muestra como forma rápida de hacerte una idea del conjunto. La forma más simple es usar sample() de pandas, así:
# Take a sample of 5
digits.sample(5)
Otra forma, quizá más compleja, es crear un índice aleatorio y extraer filas aleatorias del DataFrame. El código siguiente usa el módulo random con sample, junto con range() y len(). Fíjate en que también se usa ix para seleccionar las filas exactas que quieres incluir en la muestra.
Si no tienes claro por qué se usa ix en este contexto, el tutorial más específico de DataCamp puede ayudarte. Cubre estos temas generales en detalle. ¡Échale un vistazo en el enlace anterior!
De momento, ¡practiquemos Python! Empieza con el ejercicio siguiente:
# import `sample` from `random`
from random import ______
# Create a random index
randomIndex = np.array(sample(range(len(______)), 5))
# Get 5 random rows
digitsSample = digits.ix[___________]
# Print the sample
print(____________)
Los retos de tus datos Ahora que ya tienes información básica, conviene profundizar un poco en los retos que puede plantear tu dataset. Si ya pasaste por el data profiling, conocerás los valores ausentes, tendrás pistas sobre posibles outliers, etc.
Esta sección describe formas sencillas de detectar estos aspectos y cómo tratarlos si encuentras irregularidades. Una vez más, volverás o ya habrás ido más a fondo en la fase de data profiling, y es normal regresar a ella después de abordar algunos de los retos.
Valores ausentes Algo que también debes comprobar es si el dataset tiene valores ausentes.
Es importante porque, cuando faltan datos, el conjunto pierde capacidad explicativa y tu análisis puede quedar sesgado o ser más débil. En la práctica, si faltan valores en ciertas características, aumenta la probabilidad de que clasificaciones o predicciones se desvíen.
La causa puede ser una extracción o importación defectuosa, o el propio proceso de recogida. Los sistemas que te proporcionan datos pueden fallar o la encuesta que enviaste puede tener respuestas en blanco. También es clave considerar si hay un patrón en los datos ausentes; aquí el data profiling resulta útil para evaluar la calidad. En una publicación de seguimiento verás cómo descubrir patrones de ausencias.
En resumen, las causas son variadas y dependen del contexto, pero también de ti. ¡Por eso primero inspeccionaste los datos al importarlos!
Para identificar filas con valores ausentes, usa isnull(). En el resultado verás True o False en cada celda: True indica que el valor está ausente y False que contiene un valor “normal”.
# Identifiy missing values
pd.isnull(______)
En este caso, verás que el dataset está bastante completo: no hay valores ausentes.
Nota : también podrías haberlo visto en la descripción del dataset del UCI Machine Learning Repository enlazada arriba, donde consta que no hay valores ausentes.
No siempre será así. Por eso conviene saber qué hacer cuando te encuentras valores ausentes.
Eliminar los datos ausentes: puedes borrar el registro completo o quedarte con los registros en los que las características de interés sí estén presentes. Ojo, eliminar datos también puede sesgar el análisis. Pregúntate si la probabilidad de ausencia es la misma para todos los registros. Si no varía por registro, eliminar puede ser válido. Imputación: rellenar las celdas con valores sustitutos. Puedes usar la media, la moda o la mediana. Piensa si quieres una media/mediana global de la variable o si vas a imputar en función de otra. Por ejemplo, si tienes variables categóricas como «hombre» o «mujer», quizá te interese considerar esas categorías antes de imputar, pues las observaciones pueden diferir. En ese caso, calcula la media de «mujer» y úsala para rellenar ausencias en registros «mujer». Estimar con modelos: regresión, ANOVA, regresión logística u otras técnicas de modelado. Es la opción más compleja. Usar valores de registros similares: por ejemplo, KNN (K vecinos más cercanos). Ten en cuenta ventajas e inconvenientes de cada enfoque: tiempo, coste, naturaleza de los datos, etc. antes de decidir.
Una vez decidas qué hacer, sigue leyendo para ver cómo implementarlo.
Rellenar valores ausentes Si optas por imputar, aún puedes elegir cómo hacerlo.
Usa fillna() de pandas junto con funciones de NumPy. En el siguiente fragmento, imagina un DataFrame con resultados de una encuesta sobre salario. En un contexto donde toda la audiencia pertenece a la misma clase social y la probabilidad de responder es similar, puedes calcular la media de quienes sí respondieron y usarla para rellenar los valores faltantes.
# Import NumPyimport numpy as np# Calculate the meanmean = np. mean ( df. Salary) # Replace missing values with the meandf. = df. Salary. fillna ( mean) Con la tecnología de Por supuesto, no tienes por qué pasar un valor a fillna(): también puedes propagar valores no nulos hacia delante o hacia atrás con el argumento method. Pasa ffill o bfill para indicar la dirección.
Eliminar etiquetas con valores ausentes Para excluir columnas o filas con valores ausentes, usa dropna() de pandas:
# Drop rows with missing valuesdf. dropna ( axis= 0 ) # Drop columns with missing values df. dropna ( axis= 1 ) Con la tecnología de Interpolación Otra opción es interpolar: interpolate() realiza una interpolación lineal en los puntos con datos faltantes para “estimar” el valor más probable.
df. interpolate ( ) Con la tecnología de Puedes añadir el argumento method para usar métodos más avanzados como interpolación polinómica o cúbica, aunque para estos necesitarás SciPy.
La interpolación tiene límites, sobre todo si los NaN están muy lejos de la última observación válida. En esos casos, añade un argumento limit con un entero positivo que determine cuántos valores tras un no-NaN se rellenarán. La dirección por defecto es hacia delante, pero puedes cambiarla con limit_direction.
Valores atípicos (outliers) Al igual que con los ausentes, tu dataset puede contener valores que se desvían mucho de la mayoría. Son los “outliers”. Para encontrarlos, revisa la distribución de variables con un box plot o usa un diagrama de dispersión para identificar puntos que no caen en la zona “esperada”.
Las causas pueden variar, desde errores de sistema hasta introducción o procesamiento manual, pero es importante considerar su efecto: alteran resultados de pruebas estadísticas como desviación estándar, media o mediana, pueden reducir la normalidad y afectar a modelos como regresión o ANOVA.
Para tratarlos, puedes eliminarlos, transformarlos o imputarlos, según el contexto. De nuevo, es clave entender los datos e identificar la causa:
Si se deben a errores de introducción o procesamiento, quizá convenga eliminarlos. Puedes transformarlos asignando pesos a observaciones o aplicando logaritmos para reducir la variación que provocan. Como con los ausentes, puedes imputar reemplazando valores extremos por mediana, media o moda. Puedes reutilizar las funciones de la sección anterior para gestionar outliers.
Las características de tus datos Nota : este paso se realiza de forma iterativa con otras tareas de ciencia de datos: construyes y validas modelos, ajustas características y vuelves a iterar, etc.
Patrones en tus datos El siguiente paso en la exploración es identificar patrones, como correlaciones entre atributos o entre datos ausentes. La visualización ayuda mucho; y no tiene por qué ser estática: atrévete con visualizaciones interactivas con Bokeh o Plotly.
Identificación de correlaciones con Matplotlib Ahora que has mirado números y analizado cuantitativamente, también es útil considerar los datos de forma visual.
Para hacerlo fácil y rápido, usa Matplotlib. El único obstáculo, irónicamente, son tus datos: como sabes, tienen 64 columnas o características. Con tantas variables, hablamos de datos de alta dimensionalidad.
Qué es exactamente la dimensionalidad lo verás en nuestro tutorial de machine learning, pero por ahora basta con entender que, si quieres visualizar en 2D o 3D, necesitas dos o tres dimensiones. Es decir, debes reducir la dimensionalidad.
Para ello usarás técnicas de reducción, como el análisis de componentes principales (PCA):
# Import `PCA` from `sklearn.decomposition`
from sklearn.decomposition import ___
# Build the model
pca = PCA(n_components=2)
# Reduce the data, output is ndarray
reduced_data = pca.fit_transform(_______)
# Inspect the shape of `reduced_data`
reduced_data.______
# print out the reduced data
print(_______________)
Al inspeccionar los datos reducidos, verás que ahora solo hay dos columnas o características. El número de filas u observaciones sigue siendo 3823. Con el formato listo, ¡toca graficar!
La elección del gráfico adecuado ya es un gran paso, pero ¿cuál elegir?
Como estás explorando y quieres descubrir posibles correlaciones entre atributos, un diagrama de dispersión es una buena opción: te permite identificar relaciones entre las dos características obtenidas con la reducción de dimensionalidad.
import matplotlib. pyplot as pltplt. scatter ( reduced_data[ : , 0 ] , reduced_data[ : , 1 ] , c= labels, cmap = 'viridis' ) plt. show ( ) Con la tecnología de
Identificación de correlaciones con Bokeh También puedes usar Bokeh para construir un gráfico interactivo y descubrir correlaciones entre atributos. Bokeh es una biblioteca de visualización interactiva en Python orientada a navegadores modernos. Es ideal para datasets grandes o en streaming, pero como verás en el ejemplo, también sirve para datos “normales”.
El código es muy sencillo: importas los módulos necesarios, construyes el scatter plot, configuras la salida por defecto para guardar el resultado en un archivo cuando se llame a show() y, por último, llamas a show() para ver el gráfico.
# Import the necessary modulesfrom bokeh. charts import Scatter, output_file, show# Construct the scatter plotp = Scatter ( iris, x= 'Petal_length' , y= 'Petal_width' , color= "Class" , title= "Petal Length vs Petal Width" , xlabel= "Sepal Length" , ylabel= "Sepal Width" ) # Output the file output_file ( 'scatter.html' ) # Show the scatter plotshow ( p) Con la tecnología de El resultado es elegante:
Ten en cuenta que esta es una imagen estática, pero el gráfico resultante en tu notebook o terminal será interactivo. Por supuesto, es solo un ejemplo sencillo de lo que puedes hacer con Bokeh. Visita la galería de Bokeh para inspirarte o haz el curso Interactive Data Visualization with Bokeh de DataCamp.
Identificación de correlaciones con pandas Los gráficos anteriores son una forma visual de explorar la correlación entre atributos. Pero también puedes hacerlo de forma cuantitativa con corr() de pandas. Ten en cuenta que los valores NaN o nulos se excluyen del cálculo.
# Pearson correlation
iris.corr()
# Kendall Tau correlation
iris.corr('kendall')
# Spearman Rank correlation
iris.corr('spearman')
Nota : las dos últimas medidas de correlación requieren ordenar (rankear) los datos antes de calcular los coeficientes. Puedes hacerlo con rank(): en el ejercicio anterior, ya se ejecutó iris.rank() por ti.
Además, estas correlaciones parten de ciertas asunciones: la correlación de Pearson asume normalidad en las variables, relación lineal entre cada par de variables y normalidad alrededor de la recta de regresión. La de Spearman, en cambio, asume dos variables ordinales o relacionadas de alguna forma, pero no necesariamente de manera lineal.
La Tau de Kendall representa el grado de concordancia entre dos columnas de datos ordenados. La de Spearman mide el grado de asociación entre dos variables. Parecen similares, ¿verdad?
Aunque Kendall y Spearman se parezcan, difieren en el cálculo. Kendall Tau se calcula como el número de pares concordantes menos los discordantes dividido entre el total de pares. Spearman es la suma de las desviaciones al cuadrado dividida por n por n menos 1.
El coeficiente de Spearman suele ser mayor que el de Kendall, pero no siempre: será menor cuando las desviaciones entre observaciones sean muy grandes. La correlación de Spearman es muy sensible a esto, lo que puede ser útil en algunos casos.
Entonces, ¿cuál usar? Porque en realidad miden cosas distintas: Kendall Tau representa la proporción de pares concordantes frente a discordantes, mientras que Spearman no. También se puede argumentar que Kendall Tau tiene una interpretación más intuitiva y sencilla de calcular, que ofrece una mejor estimación del parámetro poblacional correspondiente y que los p-valores son más precisos en muestras pequeñas.
Consejo : añade print() para ver los resultados de correlaciones por pares entre columnas.
Como ya sabrás, la biblioteca de manipulación de datos de Python, pandas, se utiliza para trabajar y transformar datos. Para quien empieza, esto puede sugerir que solo sirve para el preprocesado, pero nada más lejos: pandas también es genial para explorar tus datos y para guardarlos una vez termines el preprocesamiento.
Además, si has seguido los tutoriales de Python de DataCamp o ya conoces lo básico de SciPy, NumPy, Matplotlib y pandas, puede venirte bien repasar parte de lo que ya has aprendido.
En el tutorial de hoy verás varias formas de explorar tus datos de forma eficiente con todos los paquetes anteriores para que puedas empezar a modelar: