Lección 10 de 29Módulo 2: Pandas - Manipulación de Datos

10. Transformación de Datos

Apply, map, merge, join y reshaping de DataFrames

20 minutos

Domina apply, map, merge, join y reshaping para transformar tus datos en el formato que necesitas para análisis.

Apply: Aplicar funciones

Apply en Series

import pandas as pd
import numpy as np

# Dataset de ejemplo
ventas = pd.Series([1200, 1450, 1100, 1800, 1950])

# Aplicar función built-in
ventas_miles = ventas.apply(lambda x: x / 1000)
print(ventas_miles)

# Función personalizada
def clasificar_venta(monto):
    if monto >= 1500:
        return "Alta"
    elif monto >= 1200:
        return "Media"
    else:
        return "Baja"

clasificacion = ventas.apply(clasificar_venta)
print(clasificacion)

Apply en DataFrames

df = pd.DataFrame({
    'producto': ['Laptop', 'Mouse', 'Teclado', 'Monitor'],
    'precio': [800, 25, 60, 300],
    'stock': [15, 50, 30, 20]
})

# Aplicar a una columna
df['precio_con_iva'] = df['precio'].apply(lambda x: x * 1.21)

# Función más compleja
def calcular_total_inventario(row):
    return row['precio'] * row['stock']

df['valor_inventario'] = df.apply(calcular_total_inventario, axis=1)
print(df)

Map: Mapear valores

# Mapear con diccionario
categorias = {
    'Laptop': 'Computadoras',
    'Mouse': 'Accesorios',
    'Teclado': 'Accesorios',
    'Monitor': 'Monitores'
}

df['categoria'] = df['producto'].map(categorias)

# Mapear con Serie
precios_descuento = pd.Series({
    'Laptop': 750,
    'Mouse': 20,
    'Teclado': 55,
    'Monitor': 280
})

df['precio_descuento'] = df['producto'].map(precios_descuento)

# Replace (similar a map pero más versátil)
df['stock'] = df['stock'].replace({15: 20, 50: 45})

Merge: Combinar DataFrames

# Dos DataFrames relacionados
ventas = pd.DataFrame({
    'venta_id': [1, 2, 3, 4],
    'producto_id': ['P001', 'P002', 'P001', 'P003'],
    'cantidad': [2, 5, 1, 3],
    'total': [1600, 125, 800, 900]
})

productos = pd.DataFrame({
    'producto_id': ['P001', 'P002', 'P003'],
    'nombre': ['Laptop', 'Mouse', 'Monitor'],
    'categoria': ['Computadoras', 'Accesorios', 'Monitores']
})

# Inner join (solo coincidencias)
df_merged = pd.merge(ventas, productos, on='producto_id', how='inner')
print(df_merged)

# Left join (todos de izquierda)
df_left = pd.merge(ventas, productos, on='producto_id', how='left')

# Right join (todos de derecha)
df_right = pd.merge(ventas, productos, on='producto_id', how='right')

# Outer join (todos)
df_outer = pd.merge(ventas, productos, on='producto_id', how='outer')

Concat: Concatenar DataFrames

# Concatenar verticalmente (apilar filas)
ventas_enero = pd.DataFrame({
    'producto': ['Laptop', 'Mouse'],
    'ventas': [10, 50]
})

ventas_febrero = pd.DataFrame({
    'producto': ['Laptop', 'Teclado'],
    'ventas': [12, 30]
})

ventas_totales = pd.concat([ventas_enero, ventas_febrero], ignore_index=True)
print(ventas_totales)

# Concatenar horizontalmente (agregar columnas)
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'C': [5, 6], 'D': [7, 8]})

df_horizontal = pd.concat([df1, df2], axis=1)

Pivot y Reshape

# Dataset de ventas por región y producto
ventas_detalle = pd.DataFrame({
    'fecha': ['2024-01-01', '2024-01-01', '2024-01-02', '2024-01-02'],
    'region': ['Norte', 'Sur', 'Norte', 'Sur'],
    'producto': ['Laptop', 'Laptop', 'Mouse', 'Mouse'],
    'ventas': [10, 15, 50, 45]
})

# Pivot table
pivot = ventas_detalle.pivot_table(
    values='ventas',
    index='region',
    columns='producto',
    aggfunc='sum',
    fill_value=0
)
print(pivot)

# Melt (inverso de pivot)
df_melted = pivot.reset_index().melt(
    id_vars='region',
    var_name='producto',
    value_name='ventas'
)

GroupBy y Agregación

# Dataset de transacciones
transacciones = pd.DataFrame({
    'fecha': pd.date_range('2024-01-01', periods=100, freq='D'),
    'producto': np.random.choice(['Laptop', 'Mouse', 'Teclado'], 100),
    'region': np.random.choice(['Norte', 'Sur', 'Este', 'Oeste'], 100),
    'cantidad': np.random.randint(1, 10, 100),
    'precio': np.random.choice([25, 60, 800], 100)
})

transacciones['total'] = transacciones['cantidad'] * transacciones['precio']

# GroupBy simple
por_producto = transacciones.groupby('producto')['total'].sum()
print(por_producto)

# Múltiples agregaciones
resumen = transacciones.groupby('producto').agg({
    'cantidad': ['sum', 'mean'],
    'total': ['sum', 'mean', 'max']
})
print(resumen)

# GroupBy con múltiples columnas
por_region_producto = transacciones.groupby(['region', 'producto'])['total'].sum()
print(por_region_producto)

Proyecto práctico completo

# Simular sistema de e-commerce con múltiples tablas
np.random.seed(42)

# Tabla de clientes
clientes = pd.DataFrame({
    'cliente_id': range(1, 51),
    'nombre': [f'Cliente {i}' for i in range(1, 51)],
    'tipo': np.random.choice(['Nuevo', 'Regular', 'VIP'], 50),
    'ciudad': np.random.choice(['Madrid', 'Barcelona', 'Valencia'], 50)
})

# Tabla de productos
productos = pd.DataFrame({
    'producto_id': ['P001', 'P002', 'P003', 'P004', 'P005'],
    'nombre': ['Laptop Pro', 'Mouse Gamer', 'Teclado RGB', 'Monitor 27"', 'Webcam HD'],
    'categoria': ['Computadoras', 'Accesorios', 'Accesorios', 'Monitores', 'Accesorios'],
    'precio': [1200, 45, 80, 350, 90]
})

# Tabla de órdenes
ordenes = pd.DataFrame({
    'orden_id': range(1, 201),
    'cliente_id': np.random.randint(1, 51, 200),
    'producto_id': np.random.choice(['P001', 'P002', 'P003', 'P004', 'P005'], 200),
    'cantidad': np.random.randint(1, 5, 200),
    'fecha': pd.date_range('2024-01-01', periods=200, freq='D')
})

print("="*70)
print("ANÁLISIS DE E-COMMERCE CON TRANSFORMACIONES")
print("="*70)

# 1. Combinar todas las tablas
df_completo = ordenes.merge(clientes, on='cliente_id', how='left')
df_completo = df_completo.merge(productos, on='producto_id', how='left', suffixes=('_orden', '_producto'))

# 2. Calcular métricas
df_completo['total'] = df_completo['cantidad'] * df_completo['precio']

# 3. Análisis por tipo de cliente
por_tipo_cliente = df_completo.groupby('tipo').agg({
    'orden_id': 'count',
    'total': ['sum', 'mean'],
    'cantidad': 'sum'
}).round(2)

por_tipo_cliente.columns = ['Órdenes', 'Ingresos Totales', 'Ticket Promedio', 'Unidades']
print("\n📊 ANÁLISIS POR TIPO DE CLIENTE:")
print(por_tipo_cliente)

# 4. Top productos por categoría
top_productos = df_completo.groupby(['categoria', 'nombre_producto']).agg({
    'total': 'sum',
    'cantidad': 'sum'
}).sort_values('total', ascending=False).head(10)

print("\n🏆 TOP PRODUCTOS:")
print(top_productos)

# 5. Crear tabla pivot: Ciudad vs Categoría
pivot_ciudad_cat = df_completo.pivot_table(
    values='total',
    index='ciudad',
    columns='categoria',
    aggfunc='sum',
    fill_value=0
).round(2)

print("\n🗺️ VENTAS POR CIUDAD Y CATEGORÍA:")
print(pivot_ciudad_cat)

# 6. Tendencia mensual
df_completo['mes'] = df_completo['fecha'].dt.to_period('M')
tendencia_mensual = df_completo.groupby('mes')['total'].sum()

print("\n📈 TENDENCIA MENSUAL:")
print(tendencia_mensual)

Resumen de la lección

apply() ejecuta funciones en Series o DataFrames ✅ map() mapea valores basándose en diccionarios ✅ merge() combina DataFrames (join SQL) ✅ concat() apila DataFrames vertical u horizontalmente ✅ pivot_table() reorganiza datos en formato tabla pivote ✅ groupby() agrupa y agrega datos


🎯 Próxima lección: 11. Agrupación y Agregación

En la siguiente lección profundizarás en GroupBy, pivot tables y agregaciones complejas. 🚀

¿Completaste esta lección?

Marca esta lección como completada. Tu progreso se guardará en tu navegador.