Ir al contenido principal

Análisis exploratorio de cervezas artesanas: perfilado de datos

En este tutorial, aprenderás qué es el análisis exploratorio de datos (EDA) en Python y, en concreto, el perfilado de datos con pandas.
Actualizado 17 sept 2026  · 14 min leer

Explorar con IA

ChatGPTClaudePerplexity

Nota del editor: Jean-Nicholas Hould es científico de datos en Intel Security (Montreal) y enseña cómo iniciarse en data science en su blog.

El análisis exploratorio de datos (EDA) es un enfoque estadístico orientado a descubrir y resumir un conjunto de datos. En esta fase del proceso de ciencia de datos, quieres explorar la estructura del dataset, sus variables y cómo se relacionan entre sí.

En este artículo, te centrarás en un aspecto concreto del EDA: el perfilado de datos.

El perfilado de datos consiste en resumir tu dataset mediante estadísticas descriptivas. Para comprenderlo a fondo, conviene apoyarse en un abanico amplio de métricas. Los tipos de datos, los valores ausentes, la media, la mediana o la desviación estándar son solo algunos de los elementos que tendrás que recopilar al perfilar un conjunto de datos. El objetivo es entender bien tus datos para, después, poder consultarlos y visualizarlos de distintas maneras.

Sabe de dónde vienen tus datos

Antes de lanzarte a cualquier EDA, intenta saber todo lo posible sobre el origen de los datos que vas a analizar. Necesitas entender cómo se recogieron y cómo se han procesado. ¿Ha habido transformaciones previas que puedan afectar a tu análisis?

Deberías poder responder a estas preguntas sobre tu dataset:

  • ¿Cómo se recogió?
  • ¿Es una muestra?
  • ¿Se muestreó correctamente?
  • ¿Se ha transformado el dataset de alguna manera?
  • ¿Se conocen problemas en el conjunto de datos?

Si no entiendes de dónde provienen los datos, te costará mucho sacar conclusiones con sentido. Además, corres el riesgo de cometer errores de análisis importantes.

Asimismo, asegúrate de que el dataset esté estructurado de forma estandarizada. El formato recomendado es la tercera forma normal, también conocida como tidy data. Un dataset “ordenado” tiene estas características:

  • Cada variable ocupa una columna y contiene valores
  • Cada observación ocupa una fila
  • Cada tipo de unidad observacional forma una tabla

Respetar este formato acelerará tu análisis, ya que es compatible con multitud de herramientas y librerías.

Perfilado de datos

En este post, utilizarás un dataset de cervezas artesanas en lata del sitio CraftCans. Este conjunto solo incluye datos de cervezas enlatadas de cervecerías de los Estados Unidos. No está claro si el dataset recoge absolutamente todas las cervezas enlatadas elaboradas en EE. UU. o no. Para curarte en salud, lo consideraremos una muestra que puede contener sesgos.

Esta es la estructura de los datasets que vas a usar:

Beers:

  • ID: identificador único de la cerveza.
  • Name: nombre de la cerveza.
  • ABV: graduación alcohólica (alcohol por volumen).
  • IBU: unidades internacionales de amargor.
  • Style: estilo de la cerveza.
  • Ounces: onzas de cerveza.

Breweries:

  • ID: identificador único de la cervecería.
  • Name: nombre de la cervecería.
  • City: ciudad en la que se ubica la cervecería.
  • State: estado en el que se ubica la cervecería.

Tipos de datos

El primer paso es entender de qué está compuesto tu dataset.

¿Con qué variables estás trabajando?

Por lo general, puedes encajar los datos en una de estas categorías:

  • Numéricos
  • Categóricos
  • Texto
  • Fecha

Primero importarás los datasets que encontrarás en este repositorio con la función from_csv de pandas. También unirás los datasets de beers y breweries para facilitar el análisis más adelante.

import pandas as pd

beers = pd.DataFrame.from_csv("https://raw.githubusercontent.com/nickhould/craft-beers-dataset/master/data/craftcans_beers.csv")
breweries = pd.DataFrame.from_csv("https://raw.githubusercontent.com/nickhould/craft-beers-dataset/master/data/craftcans_breweries.csv")

beers_and_breweries = pd.merge(beers, 
                               breweries, 
                               how='inner', 
                               left_on="brewery_id", 
                               right_on="id", 
                               sort=True,
                               suffixes=('_beer', '_brewery'))

Con la librería pandas, puedes ejecutar la función dtypes para listar cada columna y su tipo de dato.

beers.dtypes

Que te devuelve el siguiente resultado:

abv           float64
ibu           float64
id              int64
name           object
style          object
brewery_id      int64
ounces        float64
dtype: object

Como ves, esta función no agrupa de forma limpia los tipos de datos. Los distintos tipos numéricos (float64 e int64) no se agrupan en una sola categoría, como nos gustaría. Además, algunas columnas aparecen como objetos, lo cual no ayuda demasiado.

Para solucionarlo, puedes crear tu propia función que determine la categoría de cada columna de un DataFrame.

def get_var_category(series):
    unique_count = series.nunique(dropna=False)
    total_count = len(series)
    if pd.api.types.is_numeric_dtype(series):
        return 'Numerical'
    elif pd.api.types.is_datetime64_dtype(series):
        return 'Date'
    elif unique_count==total_count:
        return 'Text (Unique)'
    else:
        return 'Categorical'

def print_categories(df):
    for column_name in df.columns:
        print(column_name, ": ", get_var_category(df[column_name]))

Beers variables

print_categories(beers)

El comando anterior te devuelve:

abv :  Numerical
ibu :  Numerical
id :  Numerical
name :  Categorical
style :  Categorical
brewery_id :  Numerical
ounces :  Numerical

Breweries variables

print_categories(breweries)

Que te devuelve el siguiente resultado:

name :  Categorical
city :  Categorical
state :  Categorical
id :  Numerical

Con esta información, ya puedes entender mejor el dataset. Sabes que solo tienes datos categóricos y numéricos. Las variables numéricas permiten extraer muchas métricas diferentes, como la media, la desviación estándar, etc. Las variables categóricas suelen ser útiles para segmentar y agrupar la información. Por ejemplo, puede interesarte ver cómo varía el IBU entre los distintos estilos de cerveza.

Estadística descriptiva

En esta sección, recorrerás distintas estadísticas descriptivas para comprender mejor los datos. Verás que cada métrica por separado aporta poco; es la combinación de varias donde realmente se extrae valor.

Nos centraremos en la variable IBU porque es numérica. Este tipo de variables ofrece un abanico más amplio de medidas que las categóricas. Aun así, también puedes calcular métricas sobre variables categóricas, aunque con más limitaciones.

Longitud

La función len cuenta el número de observaciones en una Series. Cuenta todas las observaciones, haya o no valores ausentes o nulos.

length = len(beers["ibu"])
print(length)

En esta Series tenemos un total de 2410 observaciones.

Recuento

La función count devuelve el número de observaciones no NA/no nulas en una Series.

count = beers["ibu"].count()
print(count)

Como ves, hay 1405 observaciones no nulas en la Series.

Valores ausentes

Con la Length y el Count, ya podemos calcular cuántos valores faltan. Es la diferencia entre la Length y el Count.

number_of_missing_values = length - count
pct_of_missing_values = float(number_of_missing_values / length)
pct_of_missing_values = "{0:.1f}%".format(pct_of_missing_values*100)
print(pct_of_missing_values)

Para expresarlo en porcentaje, divide el número de valores ausentes entre el total de observaciones (la longitud). La función float asegura que se conserven los decimales en la división. La función format formatea el número como un porcentaje.

En este caso, falta casi un 42% de la variable IBU. Es importante saberlo porque afectará a tu análisis. La mayoría de estadísticas descriptivas ignorarán esos valores ausentes y eso puede introducir sesgo.

Valor mínimo/máximo

Puedes obtener el valor mínimo y máximo fácilmente con las funciones min y max sobre una Series.

print("Minimum value: ", beers["ibu"].min())
print("Maximum value: ", beers["ibu"].max())

Los valores mínimo y máximo ayudan a entender el rango de una variable. En este caso, el IBU va de 4 a 138.

Moda

La moda es el valor más frecuente en un conjunto de datos. Puedes obtenerla con la función mode sobre una Series.

print(beers["ibu"].mode())

En una distribución normal, la moda coincide con la mean y la median.

En nuestro caso, la moda de IBU es 20. Es el valor más frecuente del dataset.

Media

La media es una medida de tendencia central. Es la suma de los valores dividida entre el número de observaciones no ausentes.

Se obtiene con la función mean sobre una Series.

mean = beers["ibu"].mean()

La media es sensible a los valores atípicos: unos pocos extremos pueden desplazarla notablemente hacia arriba o abajo.

Mediana

La mediana también es una medida de tendencia central. Es el valor situado exactamente en el centro de una lista ordenada de valores numéricos.

median = beers["ibu"].median()

En distribuciones sesgadas, la mediana suele ser una medida mucho más representativa que la media.

En la distribución de IBU, la media y la mediana están en el mismo orden de magnitud.

Desviación estándar

La desviación estándar es una medida de dispersión. Un valor alto indica que los datos están muy dispersos. Se expresa en la misma unidad que los valores.

standarddev = beers["ibu"].std()

En este caso, la desviación estándar es ~26 (25.954065911259324, con exactitud). Si la distribución de IBU fuese normal, ~68% de las observaciones estarían a una desviación estándar de la media.

Estadística de cuantiles

Los cuantiles son puntos de corte que dividen una distribución en partes iguales. Muchos cuantiles tienen nombre propio. Si divides una distribución en cuatro grupos iguales, el cuantil se denomina quartile. Puedes crear cuantiles fácilmente con la función quantile sobre una Series. Esta función recibe una lista con los cuantiles a calcular. Abajo dividimos la distribución en cuatro grupos iguales.

quantile = beers["ibu"].quantile([.25, .5, .75])
0.25 21.0
0.50 35.0
0.75 64.0
Name: ibu, dtype: float64

Como ves, el cuantil 50% equivale a la mediana: es el valor que parte el dataset por la mitad. También puedes observar que el 75% de las observaciones son iguales o inferiores a 64 IBU. Además, el 50% de la distribución se sitúa entre 21 y 64 IBU. Ten en cuenta que estas métricas no consideran los valores ausentes.

Gráficos de distribución

Las visualizaciones son muy útiles en el análisis exploratorio. En este artículo no profundizaremos en el tema, pero no podemos hablar de perfilado sin mencionar la importancia de un gráfico de distribución de frecuencias. Es una de las visualizaciones más sencillas y potentes: muestra la frecuencia de cada valor en el dataset.

Para crearla, usamos la librería seaborn`` library with thedisplotfunction. This function expects aSeries` sin valores ausentes.

import seaborn as sns
sns.set(color_codes=True)
sns.set_palette(sns.color_palette("muted"))

sns.distplot(beers["ibu"].dropna());

distribution plot

En este gráfico de distribución se aprecian claramente algunos valores que ya calculamos. El valor mínimo está cerca de 0 IBU y el máximo, cerca de 140 IBU. También se ve que el valor más frecuente ronda los 20 IBU. Además, aparece un pico próximo a 60 IBU.

¿Por qué hay dos picos en esta distribución?

¿Qué lo explica? Es algo que podemos explorar en una segunda fase del EDA.

Correlaciones

Las correlaciones son una gran forma de descubrir relaciones entre variables numéricas. Hay varias maneras de calcularlas. El coeficiente de correlación de Pearson es un enfoque muy utilizado que mide la dependencia lineal entre dos variables. El coeficiente va de -1 a 1: 1 indica correlación positiva total, -1 negativa total y 0 indica que no hay correlación lineal. Podemos calcularlo con la función corr sobre un Series. Por defecto, usa Pearson, aunque permite otros métodos.

beers[["abv", "ibu", "ounces"]].corr()
  abv ibu ounces
abv 1 0.670621 0.172529
ibu 0.670621 1 0.054691
ounces 0.172529 0.054691 1

Como es lógico, la correlación de IBU consigo mismo es 1. Más interesante: la correlación entre ABV e IBU es 0.670621. No es una correlación perfecta, pero sí alta. Es un aspecto interesante para investigar más adelante.

Algunas notas sobre variables no numéricas

Las métricas anteriores aplican sobre todo a valores numéricos. Si trabajas con otros tipos de datos, como los categóricos, aún puedes extraer información útil. Por ejemplo, calcular la frecuencia de cada valor en el dataset.

Los DataFrame tienen una función llamada describe que resume el conjunto de datos. Si tu DataFrame solo contiene valores categóricos o de texto, el resumen se adapta específicamente a ese tipo de datos.

beers[["name", "style"]].describe()
  name style
count 2410 2405
unique 2305 99
top Nonstop Hef Hop American IPA
freq 12 424

Librerías para perfilado

Como has visto, recopilar estadísticas descriptivas puede ser laborioso. Por suerte, existen librerías que hacen todo el trabajo por ti y generan un perfil claro de tus datos. pandas-profiling es una de ellas. Ofrece un perfilado estadístico listo para usar. Como nuestro dataset está ordenado y estandarizado, podemos aplicarla directamente.

import pandas_profiling 

pandas_profiling.ProfileReport(beers_and_breweries)

Más preguntas

Por lo general, una vez has perfilado tu dataset, surgen más preguntas que al principio. Y eso es positivo: esas preguntas alimentarán tu EDA.

Aquí tienes algunas que nos han surgido durante el perfilado:

  • El 41,7% de los valores de IBU faltan. ¿Por qué? ¿Cómo puede afectar al análisis?
  • Hay dos picos en la distribución de IBU. ¿Qué lo explica?
  • ¿Qué explica la correlación entre IBU y ABV? ¿Qué influencia tiene el estilo de cerveza en esa correlación?
  • ¿Existen diferencias en IBU, ABV o Style entre regiones geográficas? ¿Y entre la Costa Este y la Costa Oeste?

El perfilado de datos no es un proceso lineal. A medida que filtres y segmentes tu dataset, volverás sobre él para calcular estadísticas descriptivas en subgrupos.

Próximos pasos

En este artículo has visto cómo perfilar un dataset. Ya sabes cómo asignar variables a grupos de tipos de datos específicos. También has calculado distintas estadísticas descriptivas y sabes interpretarlas. Por último, has visto que hay librerías que te ahorran el trabajo de cálculo para perfilar tus datos. Y, lo más importante, has generado más preguntas que nunca para impulsar tu análisis exploratorio.

Echa un vistazo al tutorial de análisis exploratorio de datos en Python de DataCamp.

Temas
Análisis de datos
Ciencia de datos
Python

Aprende más sobre Python

Curso

Análisis de datos bayesiano en Python

4 h
16.1K
Descubre todas las ventajas del análisis bayesiano de datos y aplícalo a una gran variedad de casos de uso reales.
Ver detallesRight Arrow
Iniciar Curso
Ver másRight Arrow
Relacionado

blog

¿Qué es el análisis de datos? Una guía experta con ejemplos

Explora el mundo del análisis de datos con nuestra completa guía. Conoce su importancia, proceso, tipos, técnicas, herramientas y principales carreras en 2023
Matt Crabtree's photo

Matt Crabtree

10 min

data-frames-in-python-banner_cgzjxy.jpeg

Tutorial

Tutorial de Pandas: DataFrames en Python

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

Karlijn Willems

15 min

Tutorial

Pandas Profiling (ydata-profiling) en Python: Guía para principiantes

Aprenda a utilizar la biblioteca ydata-profiling en Python para generar informes detallados de conjuntos de datos con muchas características.
Satyam Tripathi's photo

Satyam Tripathi

9 min

Tutorial

Tutorial seleccionar columnas con Python

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

DataCamp Team

7 min

Tutorial

Introducción al trazado con Matplotlib en Python

Este tutorial muestra cómo utilizar Matplotlib, una potente biblioteca de visualización de datos en Python, para crear gráficos de líneas, barras y dispersión con datos bursátiles.

Kevin Babitz

25 min

Tutorial

pandas read_csv() Tutorial: Importar datos

Importar datos es el primer paso de cualquier proyecto de ciencia de datos. Aprende por qué los científicos de datos actuales prefieren la función pandas read_csv() para hacerlo.
Kurtis Pykes 's photo

Kurtis Pykes

10 min

Ver MásVer Más