Metodología: La Base de Nuestra Aventura de Limpieza

Para abordar los problemas comunes de limpieza de datos de manera práctica, he seleccionado dos datasets que nos permitirán explorar a fondo cada técnica. Mi objetivo es que veas cómo se aplican estas soluciones en escenarios reales y, sobre todo, que puedas replicar los ejemplos en tu propio entorno.

Selección de Datasets

He optado por dos enfoques diferentes para los datos, buscando cubrir una gama de problemas que encontrarás en tu día a día como científico de datos:

  • Dataset 1: Titanic (de la librería Seaborn). Este dataset clásico es excelente para demostrar el manejo de valores nulos, ya que presenta ausencias significativas en columnas clave como ‘Age’, ‘Cabin’ y ‘Embarked’. Además, aunque no es su problema principal, podemos buscar duplicados.
  • Dataset 2: Un dataset personalizado en CSV. He creado un pequeño archivo CSV específicamente diseñado para mostrar problemas de formatos inconsistentes, duplicados obvios y diferentes tipos de datos que requieren conversión. Esto me permite controlar exactamente los “errores” para una demostración clara.

Obtención e Inspección Inicial de Datos

Antes de sumergirnos en la limpieza, el primer paso es siempre cargar los datos e inspeccionar su estado inicial. Esto nos da una instantánea de los problemas que necesitamos resolver. Aquí te muestro cómo cargar y obtener un primer vistazo de nuestros datasets.

Dataset Titanic

El dataset de Titanic se puede cargar directamente desde la librería Seaborn, lo que simplifica mucho el proceso. Una vez cargado, utilizaremos .info() para ver los tipos de datos y la cantidad de valores no nulos, .head() para una vista preliminar de las primeras filas, y .isnull().sum() para cuantificar los valores nulos por columna.


import pandas as pd
import seaborn as sns

# Cargar el dataset de Titanic
df_titanic = sns.load_dataset('titanic')

print("--- Información inicial del Dataset Titanic ---")
print(df_titanic.info())

print("\n--- Primeras 5 filas del Dataset Titanic ---")
print(df_titanic.head())

print("\n--- Conteo de valores nulos en el Dataset Titanic ---")
print(df_titanic.isnull().sum())


📊 Salida:

--- Información inicial del Dataset Titanic ---

RangeIndex: 891 entries, 0 to 890
Data columns (total 15 columns):
 #   Column       Non-Null Count  Dtype   
---  ------       --------------  -----   
 0   survived     891 non-null    int64   
 1   pclass       891 non-null    int64   
 2   sex          891 non-null    str     
 3   age          714 non-null    float64 
 4   sibsp        891 non-null    int64   
 5   parch        891 non-null    int64   
 6   fare         891 non-null    float64 
 7   embarked     889 non-null    str     
 8   class        891 non-null    category
 9   who          891 non-null    str     
 10  adult_male   891 non-null    bool    
 11  deck         203 non-null    category
 12  embark_town  889 non-null    str     
 13  alive        891 non-null    str     
 14  alone        891 non-null    bool    
dtypes: bool(2), category(2), float64(2), int64(4), str(5)
memory usage: 100.4 KB
None

--- Primeras 5 filas del Dataset Titanic ---
   survived  pclass     sex   age  ...  deck  embark_town  alive  alone
0         0       3    male  22.0  ...   NaN  Southampton     no  False
1         1       1  female  38.0  ...     C    Cherbourg    yes  False
2         1       3  female  26.0  ...   NaN  Southampton    yes   True
3         1       1  female  35.0  ...     C  Southampton    yes  False
4         0       3    male  35.0  ...   NaN  Southampton     no   True

[5 rows x 15 columns]

--- Conteo de valores nulos en el Dataset Titanic ---
survived         0
pclass           0
sex              0
age            177
sibsp            0
parch            0
fare             0
embarked         2
class            0
who              0
adult_male       0
deck           688
embark_town      2
alive            0
alone            0
dtype: int64

Dataset Personalizado (CSV)

Para el dataset personalizado, lo crearemos programáticamente y lo guardaremos como un archivo CSV. Esto asegura que el ejemplo sea completamente reproducible sin necesidad de descargar archivos externos. Luego, lo cargaremos y realizaremos una inspección similar para identificar duplicados y posibles inconsistencias de formato y tipo de dato.


import pandas as pd
import numpy as np

# Crear un DataFrame con problemas de limpieza
data = {
    'ID': [1, 2, 3, 4, 5, 1, 6, 7],
    'Nombre': ['Alice', 'Bob', 'Charlie', 'Alice', 'David', 'Alice', 'Eve', 'Frank'],
    'Fecha_Registro': ['2023-01-01', '02/01/2023', '2023-1-3', '2023-01-01', '2023/01/05', '01-01-2023', np.nan, '2023-01-07'],
    'Edad': [24, 30, 22, 24, 35, 24, 29, 40],
    'Ciudad': ['New York', 'Los Angeles', 'Chicago', 'New York', 'Houston', 'New York', 'Miami', 'Chicago'],
    'Ingresos': [50000, 60000, 45000, '50,000', 75000, 50000, 55000, '65000 USD']
}
df_custom = pd.DataFrame(data)

# Guardar el DataFrame a un archivo CSV temporal
csv_file_path = 'problemas_limpieza.csv'
df_custom.to_csv(csv_file_path, index=False)

# Cargar el dataset desde el CSV para simular una carga real
df_custom_loaded = pd.read_csv(csv_file_path)

print("\n--- Información inicial del Dataset Personalizado ---")
print(df_custom_loaded.info())

print("\n--- Primeras 5 filas del Dataset Personalizado ---")
print(df_custom_loaded.head())

print("\n--- Conteo de valores nulos en el Dataset Personalizado ---")
print(df_custom_loaded.isnull().sum())

print("\n--- Conteo de filas duplicadas en el Dataset Personalizado (antes de limpiar) ---")
print(df_custom_loaded.duplicated().sum())

print("\n--- Valores únicos de la columna 'Ingresos' (antes de limpiar) ---")
print(df_custom_loaded['Ingresos'].unique())

print("\n--- Valores únicos de la columna 'Fecha_Registro' (antes de limpiar) ---")
print(df_custom_loaded['Fecha_Registro'].unique())


📊 Salida:

--- Información inicial del Dataset Personalizado ---

RangeIndex: 8 entries, 0 to 7
Data columns (total 6 columns):
 #   Column          Non-Null Count  Dtype
---  ------          --------------  -----
 0   ID              8 non-null      int64
 1   Nombre          8 non-null      str  
 2   Fecha_Registro  7 non-null      str  
 3   Edad            8 non-null      int64
 4   Ciudad          8 non-null      str  
 5   Ingresos        8 non-null      str  
dtypes: int64(2), str(4)
memory usage: 729.0 bytes
None

--- Primeras 5 filas del Dataset Personalizado ---
   ID   Nombre Fecha_Registro  Edad       Ciudad Ingresos
0   1    Alice     2023-01-01    24     New York    50000
1   2      Bob     02/01/2023    30  Los Angeles    60000
2   3  Charlie       2023-1-3    22      Chicago    45000
3   4    Alice     2023-01-01    24     New York   50,000
4   5    David     2023/01/05    35      Houston    75000

--- Conteo de valores nulos en el Dataset Personalizado ---
ID                0
Nombre            0
Fecha_Registro    1
Edad              0
Ciudad            0
Ingresos          0
dtype: int64

--- Conteo de filas duplicadas en el Dataset Personalizado (antes de limpiar) ---
0

--- Valores únicos de la columna 'Ingresos' (antes de limpiar) ---

['50000', '60000', '45000', '50,000', '75000', '55000', '65000 USD']
Length: 7, dtype: str

--- Valores únicos de la columna 'Fecha_Registro' (antes de limpiar) ---

['2023-01-01', '02/01/2023',   '2023-1-3', '2023/01/05', '01-01-2023',
          nan, '2023-01-07']
Length: 7, dtype: str


Con estos dos datasets en mano, estamos listos para explorar cada una de las técnicas de limpieza. Como puedes ver, el dataset de Titanic nos muestra claramente valores nulos, y el dataset personalizado nos revela duplicados, y problemas en los formatos de ‘Fecha_Registro’ e ‘Ingresos’, así como un ID duplicado. ¡Manos a la obra!


🤖 Automatiza tu trading en 5 días con Python

Únete a mi Mini-Curso gratuito por email. Aprende a extraer datos reales, crear indicadores cuantitativos y hacer backtesting profesional.