EstevezAlvarez
Python Análisis de datos Pandas

Python para análisis de datos: del CSV al insight

El análisis de datos en Python tiene un flujo bien definido: cargar, explorar, limpiar, transformar, analizar y visualizar. Dominar ese ciclo con pandas y matplotlib resuelve el 80% de los problemas reales.

Cargar CSV / DB / API Explorar shape, dtypes, nulls Limpiar nulls, tipos, outliers Transformar groupby, merge, pivot Analizar estadísticas, KPIs Visualizar gráficas, reportes
El flujo estándar de análisis: carga de datos → exploración → limpieza → transformación → análisis estadístico → visualización.

El stack de datos en Python

Tres librerías cubren casi todos los casos:

pip install pandas numpy matplotlib seaborn

Cargar y explorar los datos

El primer paso es siempre entender la forma y calidad del dataset antes de transformar nada.

import pandas as pd
import numpy as np

# Cargar desde CSV
df = pd.read_csv("ventas.csv", parse_dates=["fecha"])

# Primeras filas
print(df.head())

# Forma y tipos
print(df.shape)        # (filas, columnas)
print(df.dtypes)       # tipo de cada columna
print(df.info())       # nulos + tipos en una línea

# Estadísticas descriptivas
print(df.describe())

# Valores nulos por columna
print(df.isnull().sum())
fecha producto cantidad precio_unit total índice 0 2026-01-03 Manzana 50 1.20 60.00 1 2026-01-03 Naranja 30 0.90 27.00 2 2026-01-04 Manzana NaN 1.20 NaN ← nulo (NaN) datetime64 object (str) float64 float64 float64 int64 dtype → df.shape = (3, 5) · 3 filas, 5 columnas · 1 valor nulo en 'cantidad'
Anatomía de un DataFrame: índice (fila), columnas con tipo (dtype), y valores NaN en celdas vacías que deben tratarse antes del análisis.

Limpiar y transformar

La limpieza es la fase que más tiempo consume en proyectos reales. Los problemas más comunes son nulos, tipos incorrectos y duplicados.

# Eliminar filas con nulos en columnas críticas
df = df.dropna(subset=["cantidad", "precio_unit"])

# Rellenar nulos opcionales con la mediana
df["descuento"] = df["descuento"].fillna(df["descuento"].median())

# Convertir tipos
df["fecha"] = pd.to_datetime(df["fecha"])
df["cantidad"] = df["cantidad"].astype(int)

# Eliminar duplicados
df = df.drop_duplicates()

# Crear columna calculada
df["total"] = df["cantidad"] * df["precio_unit"]

# Extraer componentes de fecha
df["mes"]  = df["fecha"].dt.month
df["anio"] = df["fecha"].dt.year

Analizar: groupby y agregaciones

groupby es la operación más poderosa de pandas. Permite responder preguntas como «¿cuánto vendimos por producto en cada mes?» en una sola línea.

# Ventas totales por producto
ventas_producto = (
    df.groupby("producto")["total"]
    .agg(["sum", "mean", "count"])
    .rename(columns={"sum": "total_ventas", "mean": "ticket_medio", "count": "n_transacciones"})
    .sort_values("total_ventas", ascending=False)
)
print(ventas_producto)

# Evolución mensual
evolucion = df.groupby(["anio", "mes"])["total"].sum().reset_index()
print(evolucion)

# Pivot table: producto vs mes
pivot = df.pivot_table(
    values="total",
    index="producto",
    columns="mes",
    aggfunc="sum",
    fill_value=0
)
print(pivot)

Visualizar resultados

import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(12, 4))

# Gráfica de barras — top productos
ventas_producto["total_ventas"].head(10).plot(
    kind="bar", ax=axes[0], color="#4f8cff", edgecolor="white"
)
axes[0].set_title("Top 10 productos por ventas")
axes[0].set_xlabel("")
axes[0].set_ylabel("Total €")
axes[0].tick_params(axis="x", rotation=45)

# Evolución temporal
evolucion.plot(
    x="mes", y="total", kind="line",
    ax=axes[1], marker="o", color="#4f8cff"
)
axes[1].set_title("Evolución mensual de ventas")
axes[1].set_xlabel("Mes")
axes[1].set_ylabel("Total €")

plt.tight_layout()
plt.savefig("informe_ventas.png", dpi=150)
plt.show()

Exportar resultados

# Exportar a Excel con múltiples hojas
with pd.ExcelWriter("informe.xlsx", engine="openpyxl") as writer:
    ventas_producto.to_excel(writer, sheet_name="Por producto")
    evolucion.to_excel(writer, sheet_name="Evolución mensual", index=False)
    pivot.to_excel(writer, sheet_name="Pivot producto-mes")

# Exportar a CSV limpio
df.to_csv("ventas_limpias.csv", index=False, encoding="utf-8")

# Cargar en PostgreSQL
from sqlalchemy import create_engine
engine = create_engine("postgresql://user:pass@localhost/ventas_db")
df.to_sql("ventas", engine, if_exists="replace", index=False)

Próximos pasos

  1. Polars — alternativa a pandas, significativamente más rápida en datasets grandes (>1M filas) gracias a ejecución lazy y multicore nativa.
  2. DuckDB — SQL directamente sobre DataFrames o archivos Parquet, ideal para análisis ad-hoc sin servidor.
  3. scikit-learn — cuando el análisis exploratorio revela patrones que vale la pena modelar con machine learning.
  4. Jupyter + nbconvert — para flujos de análisis documentados y reproducibles que se pueden exportar a HTML o PDF.