▷ Pandas en 15 minutos — Lo básico para analizar datos hoy mismo 2026

Pandas en 15 minutos — Lo básico para analizar datos hoy mismo

Pandas es la librería de análisis de datos en Python. Si vas a tocar CSVs, Excel, datos tabulares, BBDD o estadísticas — antes o después acabas en pandas. La buena noticia: con cinco operaciones aprendes el 90% de lo que vas a hacer en proyectos reales. La mala: la documentación oficial es tan vasta que te puedes perder en lo accesorio.

En esta entrada te enseño los 5 patrones que cubren el 90% del uso real: cargar datos, explorarlos, filtrar, agrupar y exportar. En 15 minutos haces tu primer análisis útil. El resto es matiz que vas pillando con la práctica.

Instalación

pip install pandas

💡 ¿Aún no usas entornos virtuales? venv en Python. Antes de instalar nada serio, créalo.

Las dos estructuras: Series y DataFrame

  • Series = una columna. Como una lista con superpoderes (índice, métodos estadísticos, etc).
  • DataFrame = una tabla. Filas + columnas. Lo que vas a usar el 95% del tiempo.
import pandas as pd

# DataFrame desde un dict
df = pd.DataFrame({
    "titulo": ["Inception", "Heat", "Arrival"],
    "year": [2010, 1995, 2016],
    "rating": [8.8, 8.3, 8.0],
})

print(df)
#       titulo  year  rating
# 0  Inception  2010     8.8
# 1       Heat  1995     8.3
# 2    Arrival  2016     8.0

1) Cargar datos

El 90% del tiempo cargas de CSV, Excel o JSON:

df = pd.read_csv("peliculas.csv")
df = pd.read_excel("peliculas.xlsx", sheet_name="Hoja1")
df = pd.read_json("peliculas.json")

Pandas también lee de SQL, parquet, HTML (parsea tablas de páginas web), Google Sheets… Pero para empezar, CSV y Excel cubren todo.

💡 ¿Qué CSV tienes y cómo se lee bien? Leer y escribir CSV en Python cubre la versión sin pandas y los patrones que se mantienen.

📥 Llévate el cheatsheet de Python (gratis)

PDF de 6 páginas con lo esencial: tipos, condicionales, bucles, estructuras de datos, funciones y los errores que más vas a cometer. Para tener al lado mientras programas.

Sin spam. Te apuntas a la lista, descargas el cheatsheet y recibes contenido de Python cada semana.

2) Explorar lo que tienes

Lo primero que haces tras cargar: mirar qué hay.

df.head()              # primeras 5 filas
df.tail(10)            # últimas 10
df.shape               # (filas, columnas) → (1000, 8)
df.columns             # nombres de columnas
df.dtypes              # tipo de cada columna
df.info()              # resumen: filas + columnas + tipos + nulos
df.describe()          # estadísticas: media, std, min, max, percentiles

Si hay valores ausentes:

df.isnull().sum()      # cuenta NaN por columna
df.dropna()             # quita filas con cualquier NaN
df.fillna(0)            # reemplaza NaN por 0
df.fillna({"rating": df["rating"].mean()})   # rellena con la media

3) Seleccionar y filtrar

# Una columna
df["titulo"]                     # Series
df[["titulo", "year"]]           # DataFrame con esas columnas

# Filtrar filas (boolean masking)
df[df["rating"] > 8]
df[df["year"] >= 2010]
df[(df["rating"] > 8) & (df["year"] < 2010)]    # AND con &
df[(df["genero"] == "scifi") | (df["rating"] > 8.5)]    # OR con |

# Filtrar por valores en una lista
df[df["titulo"].isin(["Inception", "Heat"])]

# Filtrar por texto
df[df["titulo"].str.contains("Star")]
df[df["titulo"].str.startswith("The")]

# Acceso por índice (.loc / .iloc)
df.loc[0]                        # fila con índice 0
df.loc[0, "titulo"]              # fila 0, columna titulo
df.iloc[0]                       # primera fila (posicional)
df.iloc[0:3, 0:2]                # primeras 3 filas, primeras 2 columnas

⚠️ Atención: & y | (no and/or) y SIEMPRE entre paréntesis: (df["x"] > 5) & (df["y"] < 10). Sin paréntesis, la precedencia te traiciona.

4) Crear / modificar columnas

# Nueva columna
df["decada"] = (df["year"] // 10) * 10
df["rating_alto"] = df["rating"] > 8

# Operación entre columnas
df["beneficio"] = df["recaudacion"] - df["presupuesto"]

# Aplicar función
df["titulo_upper"] = df["titulo"].str.upper()
df["edad"] = df["nacimiento"].apply(lambda d: 2026 - d)

# Renombrar
df = df.rename(columns={"year": "año_estreno"})

# Borrar columna
df = df.drop(columns=["columna_inutil"])

apply con lambda es útil para transformaciones custom. Para operaciones vectorizadas (más rápidas), usa los métodos de pandas (.str.lower(), .dt.year, etc.).

5) Agrupar y agregar (groupby)

Aquí pandas brilla. Aquí está el 50% del valor real:

# Media de rating por género
df.groupby("genero")["rating"].mean()

# Múltiples agregaciones
df.groupby("genero").agg({
    "rating": "mean",
    "recaudacion": "sum",
    "titulo": "count",
})

# Agrupar por varias columnas
df.groupby(["genero", "decada"])["rating"].mean()

# Reset del índice para volver a DataFrame plano
df.groupby("genero").mean().reset_index()

Patrones de agregación más comunes: mean, sum, count, min, max, std, nunique, first, last.

Ordenar

df.sort_values("rating", ascending=False)
df.sort_values(["genero", "rating"], ascending=[True, False])
df.head(10)              # tras sort, los 10 mejores

Combinar DataFrames

# Concatenar verticalmente (filas)
pd.concat([df1, df2])

# Concatenar horizontalmente (columnas)
pd.concat([df1, df2], axis=1)

# Merge (como un JOIN de SQL)
combinado = df_peliculas.merge(df_directores, on="director_id", how="left")

how: "inner" (intersección), "left" (todo lo de izquierda), "right", "outer" (unión).

Exportar

df.to_csv("salida.csv", index=False, encoding="utf-8")
df.to_excel("salida.xlsx", index=False, sheet_name="Resumen")
df.to_json("salida.json", orient="records", indent=2)
df.to_clipboard()        # copia al portapapeles, pega en Excel

index=False evita que pandas escriba el índice como una columna extra (casi siempre lo quieres así).

💡 ¿Necesitas formatear el Excel con colores y fórmulas reales? Mira Excel con openpyxl — pandas exporta lo básico, openpyxl te deja afinar.

Casos reales típicos

Top 10 películas con rating > 8 estrenadas después del 2000

top = (
    df[(df["year"] > 2000) & (df["rating"] > 8)]
    .sort_values("rating", ascending=False)
    .head(10)
)
print(top[["titulo", "year", "rating"]])

Recaudación total por director y por década

resumen = (
    df.groupby(["director", "decada"])["recaudacion"]
    .sum()
    .reset_index()
    .sort_values("recaudacion", ascending=False)
)

Limpiar dataset con valores ausentes

df = df.dropna(subset=["titulo"])                  # quita filas sin titulo
df["rating"] = df["rating"].fillna(df["rating"].median())   # rellena rating con mediana
df["genero"] = df["genero"].fillna("desconocido")  # rellena texto

Convertir string a fecha y extraer año

df["fecha"] = pd.to_datetime(df["fecha"], errors="coerce")
df["año"] = df["fecha"].dt.year
df["mes"] = df["fecha"].dt.month

💡 Para pelearte con fechas: manejar fechas en Python con datetime. Los conceptos son los mismos; pandas te da accesores .dt para vectorizar.

Pivot table

df.pivot_table(
    index="genero",
    columns="decada",
    values="rating",
    aggfunc="mean",
)

Esto te da una matriz: géneros en filas, décadas en columnas, rating medio en cada celda. Muy útil para visualizar tendencias.

Errores típicos al usar pandas

# 1. Modificar slice sin copy → SettingWithCopyWarning
filtrado = df[df["year"] > 2000]
filtrado["nuevo"] = 1     # ⚠️ pandas avisa
# Mejor:
filtrado = df[df["year"] > 2000].copy()
filtrado["nuevo"] = 1     # ✓

# 2. Usar `and`/`or` en lugar de `&`/`|`
df[df["x"] > 5 and df["y"] < 10]    # ❌ ValueError
df[(df["x"] > 5) & (df["y"] < 10)]  # ✓

# 3. Olvidar paréntesis en boolean masking
df[df["x"] > 5 & df["y"] < 10]       # ❌ orden de operadores te traiciona
df[(df["x"] > 5) & (df["y"] < 10)]   # ✓

# 4. Usar bucle for cuando hay vectorización
nuevos = []
for valor in df["rating"]:
    nuevos.append(valor * 2)
df["doble"] = nuevos
# ❌ lento
df["doble"] = df["rating"] * 2    # ✓ vectorizado, 50-100x más rápido

# 5. apply cuando hay método vectorizado
df["upper"] = df["titulo"].apply(lambda s: s.upper())
# Mejor:
df["upper"] = df["titulo"].str.upper()    # vectorizado

# 6. Comparar con NaN usando ==
df["rating"] == None       # ❌ siempre False
df["rating"].isnull()       # ✓
df["rating"].isna()         # ✓ (alias)

# 7. Olvidar reset_index() tras groupby
df.groupby("genero").mean()
# Te queda un MultiIndex confuso si hay varias columnas. Usa .reset_index() casi siempre.

Resumen — los 5 patrones que cubren el 90%

OperaciónSintaxis
Cargarpd.read_csv("..."), read_excel, read_json
Explorardf.head(), df.info(), df.describe()
Filtrardf[(df["x"] > N) & (df["y"] == "X")]
Crear columnadf["nueva"] = df["a"] + df["b"]
Agrupardf.groupby("col").agg({...}).reset_index()
Ordenardf.sort_values("col", ascending=False)
Combinardf1.merge(df2, on="id", how="left")
Exportardf.to_csv("salida.csv", index=False)

¿Te ha valido esto?

Si te ha resultado útil, llévate el cheatsheet de Python en PDF — 6 páginas con tipos, condicionales, bucles, estructuras de datos, funciones y los errores típicos. Para tener al lado mientras programas. Gratis.

Sin spam. Email + cheatsheet + un correo por semana con tutoriales nuevos.

Tu siguiente paso

Si has llegado hasta aquí, ya tienes lo necesario para abrir un CSV, explorar qué hay, filtrar, agrupar y exportar el resultado. La próxima vez que alguien te pase un Excel con 50.000 filas de ventas, abres pandas, dos groupby y un to_excel y le devuelves el resumen ejecutivo.

Si quieres aprender Python desde la base hasta proyectos reales con datos, BBDD y APIs, en El Pythonista lo enseño paso a paso.

Un abrazo,
Oscar

¿Quieres aprender Python en orden, no a saltos?

Esto que has leído es solo una pieza. En El Pythonista lo verás todo encadenado: 11 módulos, 37+ horas de vídeo, 734 actividades y un proyecto real (MovieTracker) que crece contigo desde la primera variable hasta el deploy a producción.

Ver el curso completo →

37+ horas · 734 actividades · Proyecto real · Acceso de por vida · 14 días de garantía

Compartir

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Publicar un comentario