Lección 11 de 12 · Nivel 3: Avanzado

Análisis de datos con pandas: de Excel a Python

En esta lección
  1. Preparación
  2. DataFrame y Series
  3. Seleccionar y filtrar
  4. Crear columnas y limpiar datos
  5. Resumir: groupby y tablas dinámicas
  6. Unir tablas: el BUSCARV de pandas
  7. Exportar y graficar
  8. Resumen
Lo que lograrás en esta lección
  • Cargar datos de CSV y Excel en un DataFrame y explorarlos.
  • Filtrar, ordenar, crear columnas y limpiar datos.
  • Resumir con groupby y tablas dinámicas, y unir tablas.
  • Exportar resultados a Excel y hacer un gráfico.
📥 Datos para practicar

Si prefieres no generarlo con código, descárgalo y empieza directamente con pd.read_csv("ventas.csv").

  • ventas.csv · el archivo de ventas de esta lección, listo para usar

pandas es la librería más usada del mundo para analizar datos. Hace lo mismo que Excel (filtrar, ordenar, tablas dinámicas, BUSCARV), pero con millones de filas, de forma automática y repetible. Si hiciste el curso de Excel, vas a reconocer cada concepto; si no, no pasa nada: empezamos desde cero.

Preparación

pip install pandas openpyxl matplotlib

(Dentro de tu entorno virtual, como viste en la lección 10. openpyxl permite leer y escribir Excel; matplotlib, hacer gráficos.) En Google Colab ya vienen instaladas.

Para practicar, este código crea un archivo de ventas de ejemplo:

import pandas as pd

datos = {
    "fecha": ["2026-01-05", "2026-01-12", "2026-01-20", "2026-02-03", "2026-02-15",
              "2026-02-21", "2026-03-02", "2026-03-10", "2026-03-18", "2026-03-25"],
    "region": ["Norte", "Sur", "Norte", "Centro", "Sur", "Norte", "Centro", "Sur", "Norte", None],
    "vendedor": ["Ana", "Luis", "Ana", "Eva", "Luis", "Ana", "Eva", "Luis", "Ana", "Eva"],
    "producto": ["Café", "Té", "Café", "Café", "Té", "Chocolate", "Café", "Té", "Chocolate", "Café"],
    "unidades": [120, 80, 95, 60, 110, 40, 75, 90, 55, 70],
    "precio": [12.5, 9.0, 12.5, 12.5, 9.0, 15.0, 12.5, 9.0, 15.0, 12.5],
}
pd.DataFrame(datos).to_csv("ventas.csv", index=False)

DataFrame y Series

Un DataFrame es una tabla: filas y columnas con nombre, como una hoja de Excel. Cada columna es una Series.

df = pd.read_csv("ventas.csv", parse_dates=["fecha"])
# Para Excel: pd.read_excel("ventas.xlsx", sheet_name="Datos")

print(df.head())        # primeras 5 filas
print(df.shape)         # (10, 6): filas y columnas
df.info()               # columnas, tipos y valores no nulos
print(df.describe())    # estadísticas de las columnas numéricas

Explorar primero es la regla número uno: info() te muestra que la columna region tiene un valor vacío. Lo vamos a resolver enseguida.

Seleccionar y filtrar

df["vendedor"]                         # una columna
df[["vendedor", "unidades"]]           # varias columnas (doble corchete)

df[df["region"] == "Norte"]                                   # filtrar filas
df[(df["region"] == "Norte") & (df["unidades"] > 100)]       # Y
df[(df["producto"] == "Té") | (df["producto"] == "Chocolate")] # O
df[df["producto"].isin(["Té", "Chocolate"])]                  # lo mismo, más corto

df.sort_values("unidades", ascending=False).head(3)           # top 3

Fíjate en que cada condición va entre paréntesis y se combinan con & (y) y | (o). Es la misma lógica que la función FILTRAR de Excel.

1. ¿Cómo filtras las ventas del Sur con más de 85 unidades?

  • df[df["region"] == "Sur" and df["unidades"] > 85]
  • df[(df["region"] == "Sur") & (df["unidades"] > 85)]
  • df.filter("Sur", 85)

En pandas se usa & (no and) y cada condición va entre paréntesis.

Crear columnas y limpiar datos

df["importe"] = df["unidades"] * df["precio"]       # columna calculada
df["mes"] = df["fecha"].dt.to_period("M")           # 2026-01, 2026-02...

df["region"] = df["region"].fillna("Sin región")    # rellenar vacíos
df["vendedor"] = df["vendedor"].str.strip().str.title()   # limpiar textos
df = df.drop_duplicates()                           # quitar filas repetidas

Las operaciones se aplican a toda la columna a la vez, sin bucles: es mucho más rápido y legible que recorrer las filas con for.

Columnas condicionales

Para el equivalente de SI de Excel usa numpy.where (numpy se instala junto con pandas):
import numpy as np
df["tipo"] = np.where(df["importe"] >= 1000, "Grande", "Normal")

Resumir: groupby y tablas dinámicas

df.groupby("vendedor")["importe"].sum().sort_values(ascending=False)

df.groupby("region").agg(
    ventas=("importe", "sum"),
    pedidos=("importe", "count"),
    ticket_medio=("importe", "mean"),
)

pd.pivot_table(df, values="importe", index="producto",
               columns="mes", aggfunc="sum", fill_value=0)

groupby es el SUMAR.SI.CONJUNTO de pandas; pivot_table, la tabla dinámica. El primer resultado muestra que Ana vendió 4.112,50; Eva, 2.562,50; y Luis, 2.520.

2. ¿Qué hace df.groupby("producto")["unidades"].sum()?

  • Ordena los productos alfabéticamente.
  • Suma las unidades vendidas de cada producto.
  • Cuenta cuántos productos distintos hay.

Agrupa las filas por producto y suma la columna unidades de cada grupo.

Unir tablas: el BUSCARV de pandas

metas = pd.DataFrame({"vendedor": ["Ana", "Luis", "Eva"],
                      "meta": [3000, 3000, 2500]})

resumen = df.groupby("vendedor", as_index=False)["importe"].sum()
resumen = resumen.merge(metas, on="vendedor", how="left")
resumen["cumplimiento"] = (resumen["importe"] / resumen["meta"]).round(3)
print(resumen)

merge une por una columna común. Con how="left" se conservan todas las filas de la tabla izquierda, aunque no encuentren pareja (como un BUSCARV que devuelve vacío). En el ejemplo, Ana cumple su meta al 137%, Eva al 102,5% y Luis se queda en el 84%.

Exportar y graficar

resumen.to_excel("resumen_ventas.xlsx", index=False)    # a Excel
resumen.to_csv("resumen_ventas.csv", index=False)       # a CSV

import matplotlib.pyplot as plt

por_mes = df.groupby("mes")["importe"].sum()
por_mes.plot(kind="bar", title="Ventas por mes")
plt.ylabel("Importe")
plt.tight_layout()
plt.savefig("ventas_por_mes.png")    # o plt.show() para verlo en pantalla
Errores frecuentes
  • KeyError: 'Region': los nombres de columna distinguen mayúsculas. Revisa df.columns.
  • Números leídos como texto (por ejemplo "1.250,50"): usa pd.read_csv(..., decimal=",", thousands=".").
  • Archivos con tildes que se ven mal: prueba encoding="utf-8" o encoding="latin-1".
  • CSV separados por punto y coma: sep=";".

3. Un CSV exportado de Excel en español usa punto y coma como separador. ¿Cómo lo lees?

  • pd.read_csv("archivo.csv")
  • pd.read_csv("archivo.csv", sep=";")
  • pd.read_excel("archivo.csv")

El parámetro sep indica el separador de columnas. Por defecto pandas espera comas.

Reto: el informe automático

Usando el archivo de ventas de ejemplo (o uno tuyo), escribe un script informe.py que:

  1. Cargue los datos, rellene las regiones vacías y calcule el importe.
  2. Calcule las ventas por región y por producto.
  3. Identifique el mejor mes y el vendedor con mayor ticket medio.
  4. Guarde un Excel con dos hojas (región y producto) y un gráfico PNG.
Ver una solución
import pandas as pd

df = pd.read_csv("ventas.csv", parse_dates=["fecha"])
df["region"] = df["region"].fillna("Sin región")
df["importe"] = df["unidades"] * df["precio"]
df["mes"] = df["fecha"].dt.to_period("M")

por_region = df.groupby("region")["importe"].sum().sort_values(ascending=False)
por_producto = df.groupby("producto")["importe"].sum().sort_values(ascending=False)
mejor_mes = df.groupby("mes")["importe"].sum().idxmax()
mejor_ticket = df.groupby("vendedor")["importe"].mean().idxmax()

print(f"Mejor mes: {mejor_mes} · Mayor ticket medio: {mejor_ticket}")

with pd.ExcelWriter("informe.xlsx") as writer:
    por_region.to_excel(writer, sheet_name="Region")
    por_producto.to_excel(writer, sheet_name="Producto")

ax = por_region.plot(kind="barh", title="Ventas por región")
ax.figure.tight_layout()
ax.figure.savefig("ventas_region.png")

Con los datos de ejemplo, el mejor mes es 2026-03 y el mayor ticket medio es el de Ana.

Resumen

  • pd.read_csv / pd.read_excel cargan datos; head, info y describe los exploran.
  • Filtra con condiciones entre paréntesis y & / |; crea columnas operando sobre columnas enteras.
  • groupby y pivot_table resumen; merge une tablas.
  • to_excel, to_csv y plot comunican los resultados.

En la última lección conectarás tus programas con el mundo exterior: APIs web, JSON y automatización de tareas.

¿Quieres tu certificado gratis?

Crea tu cuenta, marca tus avances y descarga el certificado al terminar el curso.

Inscribirme gratis