Skip to content
Data Wrangling: Guía Completa para Limpiar y Transformar Datos con Python

Data Wrangling: Guía Completa para Limpiar y Transformar Datos con Python

Updated on

Todo proyecto de datos comienza con la misma verdad incómoda: los datos sin procesar son desordenados. Las columnas tienen formatos inconsistentes. Las fechas llegan como strings. Los registros de clientes contienen duplicados. No puedes construir modelos, dashboards o informes confiables sobre datos en los que no confías.

Data wrangling es el proceso de convertir esos datos crudos y poco confiables en algo limpio, estructurado y listo para el análisis. Consume hasta el 80% del tiempo de un profesional de datos según múltiples encuestas de la industria. Esta guía recorre todo el pipeline de data wrangling usando Python y Pandas, con código práctico para cada paso.

📚

¿Qué es Data Wrangling?

Data wrangling (también llamado data munging) es el proceso de descubrir, estructurar, limpiar, enriquecer y validar datos sin procesar para que puedan usarse para análisis o machine learning.

Data Wrangling vs Data Cleaning vs ETL

TérminoAlcanceEnfoqueHerramientas Típicas
Data WranglingAmplio -- cubre todo el procesoExploración, reshape, limpieza, enriquecimientoPandas, Polars, scripts Python
Data CleaningEstrecho -- un subconjunto del wranglingCorregir errores, manejar valores faltantesPandas, OpenRefine, SQL
ETLNivel de sistema -- pipelines automatizadosMover datos entre sistemas a escalaAirflow, dbt, Spark

El Pipeline de Data Wrangling

1. Descubrir -- Cargar los datos y entender su forma, tipos y problemas.

2. Estructurar -- Reshape columnas y filas para que los datos coincidan con el esquema necesario.

3. Limpiar -- Manejar valores faltantes, corregir tipos de datos, eliminar duplicados.

4. Enriquecer -- Agregar columnas derivadas, unir con datasets externos.

5. Validar -- Confirmar que la salida cumple con las expectativas.

Etapa 1: Descubrir tus Datos

import pandas as pd
 
df = pd.read_csv("sales_data.csv")
 
print(f"Filas: {df.shape[0]}, Columnas: {df.shape[1]}")
df.info()
df.describe(include="all")
df.isnull().sum().sort_values(ascending=False)
print(f"Filas duplicadas: {df.duplicated().sum()}")
 
for col in df.select_dtypes(include="object").columns:
    print(f"{col}: {df[col].nunique()} valores únicos")
    print(df[col].value_counts().head(5))
    print()

Para un enfoque visual, PyGWalker (opens in a new tab) convierte cualquier DataFrame de Pandas en una interfaz interactiva tipo Tableau:

import pygwalker as pyg
walker = pyg.walk(df)

Etapa 2: Estructurar y Reshape

# Estandarizar nombres de columnas
df.columns = (
    df.columns.str.strip().str.lower().str.replace(" ", "_").str.replace(r"[^\w]", "", regex=True)
)
 
# Pivot: formato largo a ancho
sales_wide = df.pivot_table(index="product", columns="month", values="revenue", aggfunc="sum")
 
# Melt: formato ancho a largo
sales_long = sales_wide.reset_index().melt(id_vars="product", var_name="month", value_name="revenue")

Etapa 3: Limpiar los Datos

Manejo de Valores Faltantes

df_dropped = df.dropna(subset=["revenue", "customer_id"])
df["category"] = df["category"].fillna("Desconocido")
df["revenue"] = df["revenue"].fillna(df["revenue"].median())
df["price"] = df["price"].ffill()
df["temperature"] = df["temperature"].interpolate(method="linear")
SituaciónEnfoque Recomendado
Menos del 5% faltante, aleatorioEliminar filas
Columna categóricaLlenar con "Desconocido" o moda
Columna numérica, distribución normalLlenar con media
Columna numérica, distribución sesgadaLlenar con mediana
Datos de series temporalesForward fill o interpolación
Columna con > 50% faltanteConsiderar eliminar la columna

Conversiones de Tipos de Datos

df["order_date"] = pd.to_datetime(df["order_date"], format="%Y-%m-%d")
df["revenue"] = pd.to_numeric(df["revenue"], errors="coerce")
df["status"] = df["status"].astype("category")
df["is_active"] = df["is_active"].map({"yes": True, "no": False, "Y": True, "N": False})

Limpieza de Strings

df["name"] = df["name"].str.strip()
df["city"] = df["city"].str.lower()
df["phone"] = df["phone"].str.replace(r"[^\d]", "", regex=True)
df["zip_code"] = df["address"].str.extract(r"(\d{5})")

Manejo de Duplicados

print(f"Duplicados totales: {df.duplicated().sum()}")
df = df.drop_duplicates(subset=["customer_id", "order_date"], keep="first")

Etapa 4: Enriquecer -- Fusionar y Unir Datasets

merged = pd.merge(orders, customers, on="customer_id", how="left")
all_months = pd.concat([jan_df, feb_df, mar_df], ignore_index=True)
 
# Columnas calculadas
df["profit"] = df["revenue"] - df["cost"]
df["profit_margin"] = (df["profit"] / df["revenue"] * 100).round(2)
df["revenue_tier"] = pd.cut(df["revenue"], bins=[0, 100, 500, 1000, float("inf")], labels=["Bajo", "Medio", "Alto", "Premium"])
Tipo de JoinMantieneUsar Cuando
innerSolo filas coincidentesNecesitas registros completos
leftTodas las filas de la izquierdaLa tabla izquierda es tu dataset principal
rightTodas las filas de la derechaLa tabla derecha es tu dataset principal
outerTodas las filas de ambas tablasNecesitas la unión completa

Etapa 5: Validar

def validate_dataframe(df):
    checks = {}
    required = ["customer_id", "order_date", "revenue"]
    for col in required:
        null_count = df[col].isnull().sum()
        checks[f"no_nulls_{col}"] = null_count == 0
 
    neg_revenue = (df["revenue"] < 0).sum()
    checks["positive_revenue"] = neg_revenue == 0
 
    passed = sum(checks.values())
    total = len(checks)
    print(f"\nValidación: {passed}/{total} verificaciones pasaron")
    return checks
 
validate_dataframe(df)

Detección de Valores Atípicos

import numpy as np
 
Q1 = df["revenue"].quantile(0.25)
Q3 = df["revenue"].quantile(0.75)
IQR = Q3 - Q1
lower = Q1 - 1.5 * IQR
upper = Q3 + 1.5 * IQR
 
# Opción A: Eliminar
df_clean = df[(df["revenue"] >= lower) & (df["revenue"] <= upper)]
 
# Opción B: Recortar (winsorización)
df["revenue_capped"] = df["revenue"].clip(lower=lower, upper=upper)

Pandas vs Polars vs SQL

CriterioPandasPolarsSQL
VelocidadLento (single-thread)Rápido (multi-thread, Rust)Depende del motor
Mejor paraAnálisis exploratorioDatasets grandesDatos en bases de datos

Data Wrangling Asistido por IA

RunCell (opens in a new tab) trae un agente IA directamente a tu notebook Jupyter. Describe lo que necesitas en lenguaje natural y RunCell genera el código Pandas.

FAQ

¿Qué es data wrangling en términos simples?

Data wrangling es el proceso de tomar datos crudos y desordenados y convertirlos en un formato limpio y estructurado adecuado para el análisis.

¿Cuál es la diferencia entre data wrangling y data cleaning?

Data cleaning es un paso dentro de data wrangling. Cleaning se enfoca en corregir errores. Wrangling es más amplio e incluye exploración, reestructuración, enriquecimiento y validación.

¿Qué herramientas se usan para data wrangling?

Python con Pandas es la más común. Otras opciones incluyen Polars, SQL y R con dplyr. PyGWalker proporciona exploración visual interactiva.

¿Cuánto tiempo dedican los científicos de datos al data wrangling?

Las encuestas reportan que los profesionales de datos dedican 60-80% de su tiempo a data wrangling.

¿Cuáles son los pasos del data wrangling?

Los cinco pasos principales son: Descubrir, Estructurar, Limpiar, Enriquecer y Validar.

Conclusión

Data wrangling es la base que hace posible todo análisis posterior. Los puntos clave: siempre explorar antes de limpiar, usar el pipeline de cinco etapas, elegir la estrategia correcta para valores faltantes, validar la salida y documentar las decisiones.

Construye tu lógica de wrangling en funciones reutilizables. Los datos cambiarán. Las fuentes cambiarán. Tu pipeline debería manejar ambos con elegancia.

📚