📊 Taller de Análisis de Datos · Python

Explorando datos
con pandas,
matplotlib & seaborn

Una clase práctica y pedagógica para comprender el ciclo completo del análisis de datos: carga, limpieza, transformación, estadística y visualización.

Dataset
Amazon Sales Dataset

Registros
50,000 órdenes

Lenguaje
Python 3.x

Librerías
pandas · matplotlib · seaborn

🏢

¿Sobre qué vamos a trabajar?

Sector analizado

El estudio pertenece al sector de comercio electrónico (ventas de productos en línea). Este es uno de los sectores que más datos genera de forma continua y estructurada, lo que lo convierte en un terreno ideal para practicar análisis de datos.

¿Por qué este sector?

El e-commerce genera datos estructurados ideales para el análisis porque cada transacción queda registrada con precisión. Esto nos permite responder preguntas reales de negocio:

Preguntas de negocio que responderemos

¿Qué categoría vende más?  ·  ¿Cómo evolucionan los ingresos?  ·  ¿Qué variables influyen en el rendimiento comercial?

¿Por qué es rico en datos?

Cada pedido registra automáticamente múltiples variables: el producto, su precio, el descuento aplicado, las unidades, la fecha y el ingreso generado. Esto da lugar a datasets grandes, limpios y multivariados — perfectos para aprender análisis.

📊
Variables que generan valor analítico

Registros por pedido  ·  Precios y descuentos  ·  Volumen de ventas  ·  Ingresos generados  ·  Fechas para series temporales  ·  Categorías para comparar

Conjunto de datos — Variables principales

El dataset contiene información de ventas de Amazon con 50,000 registros. Estas son las columnas con las que trabajaremos durante todo el análisis:

VariableTipoSignificado
order_idint64Identificador único del pedido
order_datedatetime64Fecha en que se realizó la compra
product_idint64Identificador único del producto
product_categoryobjectCategoría del producto (Beauty, Books, Electronics, Fashion, Home & Kitchen, Sports)
pricefloat64Precio original del producto
discount_percentint64Porcentaje de descuento aplicado
quantity_soldint64Unidades vendidas en ese pedido
customer_regionobjectRegión geográfica del cliente
payment_methodobjectMétodo de pago utilizado (UPI, Credit Card, etc.)
ratingfloat64Calificación del producto (1.0 – 5.0)
review_countint64Número de reseñas del producto (se eliminará en la limpieza)
discounted_pricefloat64Precio final después de aplicar el descuento
total_revenuefloat64Ingreso total del pedido (precio descontado × unidades)
🗺️

¿Qué vamos a hacer hoy?

En este taller analizamos un conjunto de datos de ventas de Amazon con 50,000 registros. Seguiremos el ciclo completo de análisis de datos, que se puede resumir en este flujo de trabajo:

1

📥 Cargar los datos

Importar el CSV y convertirlo en un DataFrame de pandas.

2

🔍 Explorar los datos

Seleccionar columnas, filtrar registros, entender la estructura.

3

🧹 Limpiar los datos

Eliminar columnas innecesarias y filas con valores faltantes.

4

⚙️ Transformar los datos

Crear nuevas columnas derivadas y calcular métricas útiles.

5

📐 Analizar estadísticamente

Calcular medidas de tendencia central y de dispersión.

6

📈 Visualizar

Crear gráficas que comuniquen los hallazgos de forma clara.

Las tres librerías clave

pandas

La librería principal para manipulación de datos tabulares. Provee el objeto DataFrame, que funciona como una hoja de cálculo en memoria pero con el poder de Python. Permite cargar, filtrar, transformar y agrupar datos con facilidad.

matplotlib

La librería base de visualización en Python. Con ella creamos gráficos de barras, líneas, pastel e histogramas. Es muy personalizable aunque requiere más código que seaborn para lograr resultados refinados.

seaborn

Construida sobre matplotlib, seaborn facilita la creación de gráficos estadísticos más elaborados con menos código. En este proyecto la usamos para crear el mapa de calor de correlaciones.

📥

Cargando el dataset

El primer paso de cualquier análisis es cargar los datos y hacer una primera inspección para entender con qué estamos trabajando.

mision.py
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv("amazon_sales_dataset.csv")
df["order_date"] = pd.to_datetime(df["order_date"])

print(df.head())   # primeros 5 registros
print(df.info())   # estructura y tipos de datos

¿Qué hace cada línea?

📌
pd.read_csv()

Lee el archivo CSV y lo convierte en un DataFrame: una tabla de filas y columnas que vive en memoria RAM. Es equivalente a abrir un Excel dentro de Python.

📅
pd.to_datetime()

Los CSV guardan las fechas como texto ("2022-04-13"). Esta función las convierte a tipo datetime64, lo que nos permite hacer cálculos con fechas: comparar, agrupar por mes, etc.

🔎
df.head() y df.info()

head() muestra los primeros 5 registros para ver cómo lucen los datos. info() lista todas las columnas con sus tipos de datos y cuántos valores no nulos tiene cada una — esencial para detectar datos faltantes.

Resultado obtenido

Consola → df.info()
RangeIndex: 50000 entries, 0 to 49999
Data columns (total 13 columns):
 order_id          50000 non-null  int64
 order_date        50000 non-null  datetime64[ns]
 product_id        50000 non-null  int64
 product_category  50000 non-null  object
 price             50000 non-null  float64
 discount_percent  50000 non-null  int64
 quantity_sold     50000 non-null  int64
 customer_region   50000 non-null  object
 payment_method    50000 non-null  object
 rating            50000 non-null  float64
 review_count      50000 non-null  int64
 discounted_price  50000 non-null  float64
 total_revenue     50000 non-null  float64
💡
Interpretación

El dataset tiene 50,000 filas y 13 columnas. Hay columnas numéricas (float64, int64) y de texto (object). Ninguna columna tiene valores nulos en esta etapa, lo que es un buen indicio de calidad del dataset.

50,000
Registros totales
13
Columnas originales
6
Categorías de producto
2022–23
Período temporal
🎯

Seleccionar solo lo que necesitamos

No siempre necesitamos trabajar con todas las columnas. Podemos crear una vista reducida del DataFrame eligiendo solo las columnas relevantes para una tarea específica.

mision.py
selected_columns = df[['order_id', 'product_category', 'price']]
print(selected_columns)
📋
Indexación con listas de columnas

Cuando usamos df[['col1', 'col2']] (doble corchete), le pasamos una lista de nombres de columnas al DataFrame. El resultado es un nuevo DataFrame con solo esas columnas. No modifica el original.

Consola → selected_columns
       order_id product_category   price
0             1            Books  128.75
1             2          Fashion  302.60
2             3           Sports  495.80
...
49999     50000   Home & Kitchen  253.44
[50000 rows x 3 columns]
🔍

Filtrar registros con condiciones

El filtrado nos permite quedarnos solo con las filas que cumplen una determinada condición. Es equivalente al filtro de Excel, pero expresado como código.

mision.py
filtered_data = df[df['product_category'] == 'Books']
print(filtered_data)
⚙️
Indexación booleana (Boolean Indexing)

La expresión df['product_category'] == 'Books' genera una serie de True/False para cada fila. Al pasarla como índice al DataFrame, obtenemos únicamente las filas donde la condición es True. Esto se llama indexación booleana y es el mecanismo de filtrado estándar en pandas.

Consola → filtered_data (resumen)
[8327 rows x 13 columns]
→ De 50,000 registros, 8,327 son de categoría Books (≈ 16.6%)

Muestra del resultado filtrado

order_idorder_dateproduct_idproduct_category ...ratingreview_countdiscounted_pricetotal_revenue
12022-04-132637Books...3.5443115.88463.52
42022-04-172522Books...5.0212316.161264.64
72022-01-214068Books...1.641515.7878.90
92022-05-023262Books...2.8497373.621494.48
122022-11-273637Books...4.4279150.19150.19
… 8,317 registros intermedios …
499752022-12-301385Books...1.1221338.31338.31
499782022-07-264991Books...1.3273239.821199.10
499802023-05-302063Books...4.4268337.871351.48
499822023-03-143712Books...3.6407106.62106.62
499882023-01-304670Books...2.3142141.84709.20

[8,327 rows × 13 columns]

🧹

Limpiar: eliminar columnas y filas problemáticas

La limpieza de datos es una de las etapas más críticas del análisis. Datos sucios producen resultados erróneos. Los dos pasos que realizamos son: eliminar columnas irrelevantes y eliminar filas con valores faltantes.

Eliminar columna

df = df.drop(columns=["review_count"])

Removemos review_count porque no la usaremos en nuestro análisis. El método drop() recibe la lista de columnas a eliminar y devuelve un nuevo DataFrame sin ellas. Reasignamos a df para guardar el cambio.

Eliminar filas nulas

df = df.dropna()

dropna() elimina toda fila que tenga al menos un valor faltante (NaN o nulo). En este dataset todos los registros eran completos, por lo que el conteo se mantiene en 50,000 filas tras la operación.

⚠️
¿Por qué es importante la limpieza?

Los valores nulos pueden distorsionar promedios, sumas y correlaciones. Una columna irrelevante puede confundir el análisis y ocupar memoria innecesariamente. Limpiar siempre antes de analizar es una buena práctica profesional.

⚙️

Crear nuevas columnas derivadas

A partir de las columnas existentes podemos calcular métricas nuevas que son más útiles para el análisis. Esto se llama feature engineering o ingeniería de variables.

mision.py
# Ingreso por unidad = ingresos totales / unidades vendidas
df["ingreso_por_unidad"] = df["total_revenue"] / df["quantity_sold"].replace(0, 1)
📐
¿Qué mide el "ingreso por unidad"?

El ingreso total dividido entre las unidades vendidas nos da el precio efectivo promedio por unidad. Es más informativo que el precio de lista porque ya refleja los descuentos aplicados.

🛡️
.replace(0, 1) — Prevención de división por cero

Si quantity_sold fuera 0 en algún registro, dividiríamos por cero y obtendríamos inf. Al reemplazar los ceros con 1 antes de dividir, evitamos ese error. Es una técnica defensiva de programación.

Consola → primeras filas con ingreso_por_unidad
   total_revenue  quantity_sold  ingreso_por_unidad
0         463.52              4              115.88
1        1210.40              5              242.08
2         793.28              2              396.64
3        1264.64              4              316.16
4         806.72              4              201.68

Ordenar los datos

df_ordenado = df.sort_values(
    by=["product_category", "ingreso_por_unidad"],
    ascending=[True, False]
)

Ordenamos por categoría (ascendente A→Z) y dentro de cada categoría por ingreso por unidad (descendente, de mayor a menor). Esto nos permite ver fácilmente los productos más rentables de cada categoría.

📊

groupby() — El corazón del análisis agregado

Una de las operaciones más poderosas de pandas es groupby(), que nos permite calcular métricas resumidas por grupos. Es equivalente a una tabla dinámica (pivot table) de Excel.

mision.py
resumen = df.groupby("product_category").agg(
    ingreso_total=("total_revenue", "sum"),
    cantidad_total=("quantity_sold", "sum"),
    ingreso_promedio_unidad=("ingreso_por_unidad", "mean"),
    numero_ordenes=("order_id", "count")
)
🗂️
Patrón Split → Apply → Combine

groupby() divide el DataFrame en grupos (Split), aplica una función a cada grupo (Apply), y combina los resultados en un nuevo DataFrame (Combine). Le estamos diciendo: "para cada categoría de producto, calcula la suma del ingreso, la suma de unidades, el promedio del ingreso por unidad y el conteo de órdenes".

El método .agg() — Agregaciones múltiples en una sola instrucción

.agg() es la abreviatura de aggregate (agregar/resumir). Su función es aplicar una o varias operaciones de resumen a una o varias columnas del DataFrame simultáneamente. Sin .agg(), tendríamos que hacer cada cálculo en una línea separada.

Anatomía de .agg()
# Sintaxis general:
df.agg(
    nombre_resultado = ("columna_origen", "función"),
    ...
)

# En nuestro taller:
df.groupby("product_category").agg(
    ingreso_total         = ("total_revenue",     "sum"  ),  # suma
    cantidad_total        = ("quantity_sold",     "sum"  ),  # suma
    ingreso_promedio_unidad = ("ingreso_por_unidad", "mean" ),  # promedio
    numero_ordenes        = ("order_id",          "count")   # conteo
)
Parte de .agg() ¿Qué es? Ejemplo
nombre_resultado El nombre que tendrá la columna en el DataFrame de salida. Lo elegimos nosotros libremente. ingreso_total
"columna_origen" La columna del DataFrame original sobre la que se aplica la operación. "total_revenue"
"función" La operación matemática a aplicar: "sum", "mean", "count", "min", "max", "std", "median", etc. "sum"
💡
¿Por qué usar .agg() en lugar de calcular uno por uno?

Sin .agg() necesitaríamos 4 líneas separadas y luego unir los resultados manualmente. Con .agg() obtenemos un DataFrame completo y bien estructurado en una sola instrucción, con los nombres de columna que nosotros queramos. Es más legible, más eficiente y produce resultados listos para analizar o exportar.

🔁
.agg() también funciona sin groupby()

En el Bloque 7 (estadística descriptiva) usamos .agg(["mean", "median"]) directamente sobre el DataFrame, sin agrupar. En ese caso, aplica las funciones a todas las filas de las columnas seleccionadas, calculando la media y mediana globales del dataset completo.

Resultados obtenidos

Categoría Ingreso Total Cantidad Total Ing. Prom./Unidad N° Órdenes
Beauty$5,550,624.9725,422$218.688,465
Books$5,484,863.0325,065$218.748,327
Electronics$5,470,594.0324,898$218.848,320
Fashion$5,480,123.3425,089$218.648,365
Home & Kitchen$5,473,132.5524,743$220.478,258
Sports$5,407,235.8224,753$217.968,265
🔍
Hallazgo importante: distribución muy uniforme

Los ingresos por categoría son sorprendentemente parejos: todos oscilan entre $5.4M y $5.5M. Esto sugiere que o bien el dataset fue generado sintéticamente, o que Amazon ha logrado un equilibrio comercial notable entre categorías. El ingreso promedio por unidad también es casi idéntico en todas las categorías (~$218–$220).

📐

Medidas de tendencia central y dispersión

La estadística descriptiva nos permite resumir y caracterizar los datos con números clave. Se divide en dos grandes familias de métricas:

Tendencia central

estadisticas = df[[
    "ingreso_por_unidad",
    "total_revenue",
    "quantity_sold"
]].agg(["mean", "median"])
Resultado
        ing/unidad  revenue  qty
mean      218.89    657.33   2.99
median    215.81    505.41   3.00

Dispersión

dispersion = df[[
    "ingreso_por_unidad",
    "total_revenue",
    "quantity_sold"
]].agg(["var", "std"])
Resultado
      ing/unidad   revenue   qty
var    16209.79   276911.6   2.00
std      127.32     526.22   1.42
Métrica¿Qué mide?¿Cuándo usarla?
Media (mean)El promedio aritméticoCuando los datos no tienen valores extremos
Mediana (median)El valor del centro cuando ordenamos los datosCuando hay valores extremos (outliers)
Moda (mode)El valor más frecuenteEn variables categóricas
Varianza (var)Dispersión promedio al cuadradoPara cálculos matemáticos
Desviación estándar (std)Dispersión en las mismas unidades que los datosPara interpretar qué tan "esparcidos" están los datos
📊
Interpretación: Media vs Mediana del ingreso total

La media del ingreso total ($657) es mayor que la mediana ($505). Esto indica una distribución sesgada a la derecha: hay órdenes de alto valor que "jalan" la media hacia arriba. La mediana es un mejor representante del ingreso "típico". La moda de categoría es Beauty, la más frecuente.

📈

Las 5 gráficas del análisis

Las visualizaciones transforman números en historias. Cada tipo de gráfica tiene un propósito específico. Analizamos cada una en detalle.

Gráfica 1 — Barras: Ingreso total por categoría

ingresos_categoria = df.groupby("product_category")["total_revenue"].sum()

plt.figure()
ax = ingresos_categoria.plot(kind="bar")

plt.title("Ingreso total por categoria")
plt.xlabel("Categoria")
plt.ylabel("Ingreso total")
plt.xticks(rotation=45)

for i, valor in enumerate(ingresos_categoria):
    ax.text(i, valor, f"{valor/1_000_000:.2f}M", ha="center", va="bottom")
Ingreso total por categoría

Figura 1. Ingreso total acumulado por categoría de producto.

📌
¿Por qué un gráfico de barras?

Es ideal para comparar valores entre categorías discretas. Cada barra representa una categoría y su altura es proporcional al valor que queremos comparar. El loop for agrega las etiquetas de valor en millones encima de cada barra, facilitando la lectura exacta.

🔍
Análisis de la gráfica

Las barras confirman visualmente la uniformidad del dataset: todas las categorías alcanzan entre 5.41M y 5.55M de ingreso total, con barras de altura casi idéntica. Beauty lidera con $5.55M y Sports queda último con $5.41M — una brecha de apenas $143K (2.6%). Las etiquetas de valor en millones sobre cada barra facilitan la comparación exacta sin necesidad de leer el eje Y. La escala del eje Y arranca cerca de los 5M, lo que exagera visualmente las diferencias: una señal de precaución para interpretar gráficas de barras donde el eje no parte en cero.

Gráfica 2 — Líneas: Ingresos a lo largo del tiempo

df["anio_mes"] = df["order_date"].dt.to_period("M")
ingresos_fecha = df.groupby("anio_mes")["total_revenue"].sum()

ingresos_fecha.plot(kind="line")
plt.title("Ingresos a lo largo del tiempo")
Ingresos a lo largo del tiempo

Figura 2. Evolución mensual del ingreso total a lo largo del tiempo.

📅
to_period("M") — Agrupación por mes

El acceso .dt.to_period("M") convierte una fecha como 2022-04-13 al período mensual 2022-04. Esto nos permite sumar todos los ingresos de un mismo mes en una sola fila, creando la serie temporal que luego graficamos.

🔍
¿Por qué un gráfico de líneas?

Las líneas son perfectas para mostrar tendencias a lo largo del tiempo (series temporales). El eje X representa el tiempo (meses) y el eje Y los ingresos. La línea conecta los puntos y nos permite ver si los ingresos suben, bajan o fluctúan con el tiempo.

📅
Análisis de la gráfica

La gráfica muestra los ingresos mensuales de enero 2022 a diciembre 2023. Se observan fluctuaciones irregulares mes a mes, sin una tendencia clara de crecimiento o caída sostenida. Los ingresos oscilan entre ~$1.24M (mínimo en febrero 2023) y ~$1.46M (máximo en enero 2023 y julio 2022). Esta variabilidad sin patrón estacional claro refuerza la hipótesis de datos sintéticos generados aleatoriamente. En datos reales esperaríamos picos en temporadas como Black Friday o Navidad.

Gráfica 3 — Pastel: Distribución de ingresos por categoría

ingresos_categoria.plot(kind="pie", autopct="%1.1f%%")
plt.title("Distribucion de ingresos por categoria")
Distribución de ingresos por categoría

Figura 3. Proporción del ingreso total de cada categoría.

🥧
autopct="%1.1f%%" — Formato de porcentaje

El parámetro autopct agrega el porcentaje dentro de cada porción del pastel. El formato %1.1f%% significa: mostrar el número con 1 decimal y agregar el símbolo %.

🔍
Análisis de la gráfica

El pastel muestra 6 porciones de tamaño casi idéntico: Beauty 16.9%, Books 16.7%, Fashion 16.7%, Home & Kitchen 16.7%, Electronics 16.6% y Sports 16.5%. La diferencia entre la porción mayor y menor es de apenas 0.4 puntos porcentuales. En ventas reales, la ley de Pareto dictaría que el 20% de las categorías genera el 80% de los ingresos — aquí esa regla no aplica, lo que confirma el origen sintético del dataset. Sin embargo, el ejercicio es valioso porque demuestra cómo una gráfica de pastel puede revelar de un vistazo la distribución proporcional entre categorías.

Gráfica 4 — Histograma: Distribución del ingreso por unidad

ax = df["ingreso_por_unidad"].plot(kind="hist", bins=30)

media = df["ingreso_por_unidad"].mean()
mediana = df["ingreso_por_unidad"].median()

plt.axvline(media, linestyle="--", label=f"Media: {media:.2f}")
plt.axvline(mediana, linestyle="-", label=f"Mediana: {mediana:.2f}")
Distribución del ingreso por unidad

Figura 4. Distribución de frecuencias del ingreso por unidad con líneas de media y mediana.

📊
¿Qué es un histograma?

Un histograma divide el rango de valores en intervalos (bins) y muestra cuántos datos caen en cada uno. No es un gráfico de barras: aquí el eje X es continuo y no hay espacios entre las barras. Los 30 bins dividen el rango de ingresos en 30 intervalos iguales.

↕️
axvline() — Líneas verticales de referencia

plt.axvline() dibuja una línea vertical en el valor especificado. Al agregar las líneas de media y mediana, podemos ver visualmente si la distribución es simétrica o sesgada, y qué tan cerca están ambas medidas.

🔍
Análisis de la gráfica

El histograma muestra que la distribución del ingreso por unidad es aproximadamente uniforme entre $0 y $350, con frecuencias de ~1,800–2,050 registros por bin en ese rango. A partir de $350 la frecuencia cae progresivamente hasta llegar a ~250 registros en el bin de $500. Esto genera un sesgo negativo a la derecha (cola derecha): los ingresos muy altos son menos frecuentes. Las líneas de media ($218.89, línea punteada) y mediana ($215.81, línea sólida) aparecen muy juntas y en el centro de la distribución, confirmando que ambas son representativas del ingreso "típico". La etiqueta "Total datos: 50000" valida que ningún dato fue excluido.

Gráfica 5 — Mapa de calor: Correlaciones

correlacion = df[[
    "price", "discount_percent", "quantity_sold",
    "total_revenue", "ingreso_por_unidad"
]].corr()

sns.heatmap(correlacion, annot=True)
plt.title("Mapa de calor de correlacion")
Mapa de calor de correlación

Figura 5. Matriz de correlación de Pearson entre las variables numéricas del dataset.

🌡️
¿Qué es la correlación de Pearson?

La correlación mide la relación lineal entre dos variables. Su valor va de -1 (perfectamente opuestas) a +1 (perfectamente relacionadas). Un valor de 0 indica que no hay relación lineal. El mapa de calor (heatmap) colorea cada celda según su valor: colores cálidos = correlación positiva, fríos = negativa.

🔍
¿Qué buscar en el heatmap?

La diagonal principal siempre vale 1.0 (cada variable se correlaciona perfectamente consigo misma). Lo interesante es observar si price y ingreso_por_unidad están altamente correlacionados (esperamos que sí, dado que el ingreso por unidad depende del precio), y si el discount_percent afecta negativamente al ingreso por unidad.

🔍
Análisis de la gráfica — Correlaciones clave

El mapa de calor revela cuatro hallazgos importantes: (1) price ↔ ingreso_por_unidad: 0.97 — correlación casi perfecta, lógica porque el ingreso por unidad se calcula a partir del precio. (2) price ↔ total_revenue: 0.71 — correlación fuerte: a mayor precio, mayor ingreso total. (3) quantity_sold ↔ total_revenue: 0.59 — correlación moderada: más unidades vendidas generan más ingresos. (4) discount_percent ↔ ingreso_por_unidad: -0.20 — correlación negativa débil: mayores descuentos reducen ligeramente el ingreso por unidad, como es de esperar. Las correlaciones cercanas a 0 (como discount_percent ↔ price: -0.0047) indican independencia estadística — los descuentos se aplican independientemente del precio del producto.

🎓

Conclusiones del análisis

Tras completar el ciclo completo de análisis, estos son los hallazgos y lecciones principales del taller:

💰 Ingresos balanceados

Las 6 categorías de producto generan ingresos casi idénticos (~$5.4–5.5M cada una). No existe una categoría dominante: Beauty lidera y Sports queda último, pero con una brecha mínima del 2.6%.

📦 Volumen uniforme

El número de órdenes por categoría es muy similar (entre 8,258 y 8,465), y el ingreso promedio por unidad oscila alrededor de $218–$220 en todas las categorías sin variación significativa.

📅 Serie temporal

Los datos cubren los años 2022–2023. La gráfica de líneas permite identificar meses de mayor y menor actividad comercial, útil para planear inventario y campañas de marketing.

📐 Distribución sesgada

La diferencia entre media ($657) y mediana ($505) en el ingreso total revela que hay órdenes de alto valor que elevan el promedio. La mediana es el mejor indicador del ingreso "típico".

🧹 Limpieza exitosa

El dataset no presentó valores nulos, lo que facilitó el proceso. La eliminación de review_count simplificó el análisis sin perder información relevante para los objetivos del taller.

🔧 Herramientas utilizadas

Este análisis completo fue posible con solo tres librerías: pandas para manipulación, matplotlib para visualización base, y seaborn para el heatmap estadístico. Una combinación estándar en ciencia de datos profesional.

Habilidades adquiridas en este taller

Al completar este taller, ahora sabes cómo:

✅  Cargar y explorar un CSV con pandas

✅  Convertir tipos de datos (fechas)

✅  Seleccionar, filtrar y ordenar datos

✅  Eliminar columnas y filas problemáticas

✅  Crear columnas derivadas (feature engineering)

✅  Agrupar datos con groupby() y agg()

✅  Calcular estadísticas descriptivas

✅  Crear 5 tipos de visualizaciones