Pandas en Python: DataFrame, Series, read_csv, filtrado, groupby y merge

Pandas es la librería de análisis de datos de Python. Su estructura central, el DataFrame, es una tabla bidimensional con etiquetas en filas y columnas que permite cargar, limpiar, transformar y analizar datos sin necesidad de SQL ni Excel. Es la herramienta más usada en ciencia de datos, análisis de negocio y ETL con Python.

Cargar y explorar datos con read_csv()

import pandas as pd

# Cargar un CSV
df = pd.read_csv("ventas.csv", encoding="utf-8", sep=",")

# Primeras y últimas filas
print(df.head())    # primeras 5 filas
print(df.tail(3))   # últimas 3 filas

# Información del dataset
print(df.shape)     # (filas, columnas)
print(df.info())    # tipos de dato, valores no nulos
print(df.describe()) # estadísticas básicas (media, std, min, max...)

# Nombres de columnas y tipos
print(df.columns.tolist())
print(df.dtypes)
import pandas as pd
import io

# Dataset de ejemplo (en producción vendría de un CSV real)
csv_datos = """fecha,producto,categoria,unidades,precio_unitario
2024-01-05,Teclado,Electrónica,10,49.99
2024-01-05,Ratón,Electrónica,15,29.99
2024-01-12,Silla,Muebles,3,199.99
2024-01-15,Monitor,Electrónica,5,349.99
2024-02-01,Teclado,Electrónica,8,49.99
2024-02-10,Mesa,Muebles,2,299.99"""

df = pd.read_csv(io.StringIO(csv_datos), parse_dates=["fecha"])
print(df.dtypes)

Seleccionar con loc e iloc

import pandas as pd

# loc: selección por etiquetas (nombre de fila/columna)
# iloc: selección por posición numérica

# Seleccionar columnas
nombres = df["producto"]              # Serie (una columna)
varias = df[["producto", "unidades"]] # DataFrame (varias columnas)

# loc[filas, columnas] — por etiqueta
primera_fila = df.loc[0]                          # fila con índice 0
columnas = df.loc[:, ["producto", "precio_unitario"]]  # todas las filas, 2 columnas
subconjunto = df.loc[1:3, "producto":"unidades"]  # filas 1-3, columnas producto a unidades

# iloc[filas, columnas] — por posición
print(df.iloc[0])          # primera fila
print(df.iloc[-1])         # última fila
print(df.iloc[:3, :2])     # primeras 3 filas, primeras 2 columnas
print(df.iloc[1, 2])       # valor en fila 1, columna 2

Filtrar con condiciones booleanas

import pandas as pd

# Filtro simple
electronicos = df[df["categoria"] == "Electrónica"]

# Filtro compuesto
caros_y_muchos = df[(df["precio_unitario"] > 100) & (df["unidades"] >= 5)]

# isin(): comprobar si está en una lista
seleccion = df[df["producto"].isin(["Teclado", "Ratón"])]

# str accessor: filtros sobre strings
con_t = df[df["producto"].str.startswith("T")]
minusculas = df[df["categoria"].str.lower() == "electrónica"]

# query(): sintaxis más legible para filtros complejos
resultado = df.query("precio_unitario > 50 and categoria == 'Electrónica'")

print(electronicos[["producto", "unidades", "precio_unitario"]])

Columnas calculadas y transformaciones

import pandas as pd

# Nueva columna calculada
df["total"] = df["unidades"] * df["precio_unitario"]
df["con_iva"] = df["total"] * 1.21

# apply(): aplicar una función personalizada
def clasificar_precio(precio: float) -> str:
    if precio < 50:
        return "económico"
    elif precio < 200:
        return "medio"
    return "premium"

df["segmento"] = df["precio_unitario"].apply(clasificar_precio)

# Transformaciones de fechas
df["mes"] = df["fecha"].dt.month
df["año"] = df["fecha"].dt.year
df["dia_semana"] = df["fecha"].dt.day_name()

print(df[["producto", "total", "segmento", "mes"]])

groupby().agg() — agregaciones por grupo

import pandas as pd

# Total de ventas por categoría
por_categoria = df.groupby("categoria")["total"].sum()
print(por_categoria)

# Múltiples agregaciones a la vez
resumen = df.groupby("categoria").agg(
    unidades_totales=("unidades", "sum"),
    venta_total=("total", "sum"),
    precio_medio=("precio_unitario", "mean"),
    num_transacciones=("producto", "count")
)
print(resumen.round(2))

# Agrupar por múltiples columnas
por_mes_cat = df.groupby(["año", "mes", "categoria"])["total"].sum().reset_index()
print(por_mes_cat)

merge() — combinar DataFrames

import pandas as pd

# Dataset de productos con información extra
productos_info = pd.DataFrame({
    "producto": ["Teclado", "Ratón", "Monitor", "Silla", "Mesa"],
    "proveedor": ["TechCo", "TechCo", "DisplayPro", "FurnitureCo", "FurnitureCo"],
    "stock_almacen": [50, 80, 20, 15, 10]
})

# Inner join (solo registros que coinciden en ambos DataFrames)
combinado = df.merge(productos_info, on="producto", how="inner")
print(combinado.head())

# Left join (todos los de df, NaN donde no hay coincidencia)
completo = df.merge(productos_info, on="producto", how="left")

# Resumen post-merge: ventas por proveedor
ventas_proveedor = combinado.groupby("proveedor")["total"].sum().sort_values(ascending=False)
print(ventas_proveedor)

Exportar resultados

import pandas as pd

# Guardar a CSV
df.to_csv("resultado.csv", index=False, encoding="utf-8")

# Guardar a Excel
df.to_excel("resultado.xlsx", sheet_name="Ventas", index=False)

# Guardar a JSON
df.to_json("resultado.json", orient="records", force_ascii=False, indent=2)

# Guardar a Parquet (formato columnar eficiente)
# pip install pyarrow
df.to_parquet("resultado.parquet", index=False)

# Leer Parquet
df_parquet = pd.read_parquet("resultado.parquet")

El flujo típico con Pandas: read_csv() para cargar, info() y describe() para entender los datos, filtros booleanos para seleccionar subconjuntos, columnas calculadas para transformar, groupby().agg() para resumir, merge() para enriquecer con otras fuentes y to_csv() o to_excel() para exportar. Con esas seis operaciones resuelves la mayoría de los análisis de datos del día a día.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP