Una Guía Práctica Para La Limpieza De Datos

Soner Yıldırım
Jun 09, 2020

Contents Outline

Una Guía Práctica Para La Limpieza De Datos

Jun 09, 2020 5 minutes read

El combustible de todos y cada uno de los modelos de aprenziaje automático y aprendizaje profundo son los datos. Sin datos, los modelos son inútiles. Antes de construir un modelo y entrenarlo, debemos tratar de explorar y entender los datos que tenemos a mano. 

Por entender, me refiero a las correlaciones, estructuras, distribuciones, características y tendencias de los datos. Una comprensión completa de los datos será muy útil para construir un modelo robusto y bien diseñado. Podemos sacar conclusiones valiosas explorando los datos. Antes de empezar a explorar los datos, necesitamos limpiar y reformatear los datos para que puedan ser fácilmente analizados.

En este post, caminaremos a través del proceso de limpieza de datos del dataset de "obesidad entre adultos por país". Cubriré la parte del análisis exploratorio de datos en un post separado. Será demasiado largo de enfocar a los lectores si los combinamos en un solo post.




El dataset contiene las tasas de obesidad de adultos en 195 países entre 1975 y 2016. Empecemos leyendo el conjunto de datos en un marco de datos de Pandas y echémosle un vistazo:

import numpy as np
import pandas as pd
df = pd.read_csv("obesity_data.csv")
df.shape
df.head()


Definitivamente no está en un formato atractivo. Las tres primeras filas parecen repetir la misma información. Podemos confirmarlo usando la función nunique en las filas:

print(df.iloc[0, :].unique())
[nan, 'Prevalence of obesity among adults, BMI ≥ 30 (age-standardized estimate) (%)']


Las dos primeras filas contienen el mismo valor en todas las columnas excepto en la primera y ese valor es NaN (Not a number). La tercera columna indica el género pero podemos obtener la misma información de los nombres de las columnas. 2016.1 es masculino, 2016.2 es femenino y 2016 es el promedio y esto es válido para todos los años. Las tres primeras filas son redundantes, así que las removeremos

df.drop([0,1,2], axis=0, inplace=True)
df.reset_index(drop=True, inplace=True)

Ahora el dataframe se ve algo como:


Los valores de solo años (por ejemplo, 2016) son el promedio de las otras dos columnas del mismo año (por ejemplo, 2016.1 y 2016.2). No tiene sentido mantener una columna que podemos lograr con una simple operación matemática. Así que dejamos de lado las columnas de solo años

Lea tambiíen: Algunos Stacks Comunes Para Ciencia de Datos.

Hay un patrón en los nombres de las columnas. A partir de la segunda columna, cada tercera columna solo añol. Podemos usar este patrón para filtrar los nombres de las columnas y pasarlo a la función drop (Remover)

df.drop(df.columns[1::3], axis=1, inplace=True)
df.head()



Las columnas del año contienen un valor y un rango. El valor es la media de los límites superior e inferior del intervalo. Por lo tanto, sólo podemos tomar el valor como el promedio de la tasa de obesidad. Podemos lograrlo dividiendo los valores y el rango, y luego tomar el primer elemento después de la división.

for i in range(1,85):
    df.iloc[:,i] = df.iloc[:,i].str.split(expand=True)[0]

df.head()
`

Este formato no es muy óptimo para el análisis. Es mejor si tenemos las siguientes columnas:

  • país, año, género, tasa_de_obesidad
Así que necesitamos convertir un marco de datos amplio en uno mas acotado. La función de transpose (transponer) de pandas puede ser usada para esta tarea pero hay una opción mucho mejor que es la función melt (fusionar) de pandas. Considero la función melt como una  "transposición inteligente".

df2 = df.melt(id_vars=['Unnamed: 0'], value_name='obesity_rate')
df2.head()

Nos estamos acercando al formato deseado. El número adjunto al año indica el género. 1 es para el hombre y 2 para la mujer. Podemos dividir la columna variable en columnas de 
"año" y "género":

df2[['year','gender']] = df2.iloc[:,1].str.split('.', expand=True)
df2.head()

Hay algunos ajustes que debemos hacer:
  • Remover la columna de "variable" porque está representada por las columnas de "año" y "género".
  • Cambiar los valores de la columna "género" para que 1 sea masculino y 2 sea femenino.
  • Cambiar el nombre de las primeras columnas a "país".
df2.drop('variable', axis=1, inplace=True)
gender = {'1':'male', '2':'female'}
df2.gender.replace(gender, inplace=True)
df2.rename(columns={'Unnamed: 0':'country'}, inplace=True)
df2.head()

Ahora tenemos un dataframe bonito y limpio. Finalmente, revisemos la forma y los tipos de datos del nuevo dataframe y busquemos los valores que faltan.

df2.shaped
df2.isna().sum()
df2.dtypes
Necesitamos cambiar el tipo de datos de la columna "tasa_de_obesidad" a un float.
 Cuando intenté convertir los valores, descubrí que hay valores "No" en la columna "tasa_obesidad" que no pueden ser convertidos a un valor numérico. Después de comprobar los valores "No", vi que sólo unos pocos países incluyen valores "No" en la columna obesity_rate:

df2[df2.obesity_rate == 'No']['country'].unique()
array(['Monaco', 'San Marino', 'South Sudan', 'Sudan'], dtype=object)
En realidad, todos los valores de estos países son "No":

omit = df2[df2.obesity_rate == 'No']['country'].unique()
df2[df2.country.isin(omit)]['obesity_rate'].unique()
df2 = df2[~df2.country.isin(omit)]

Así que los removemos: 

df2 = df2[~df2.country.isin(omit)]
El operador tilde (~) significa NO por lo que tomamos las filas para las que el país no está en la lista de omisión. Ahora podemos cambiar el tipo de datos a numérico:

df2 = df2.astype({'obesity_rate': 'float32'})
df2.dtypes
Ahora tenemos un dataframe limpio en un formato apropiado para el análisis exploratorio de datos (EDA). Cubriré un proceso detallado de EDA con visualizaciones informativas en el próximo post.

Gracias por la lectura. Por favor, háganme saber si tienen alguna respuesta.
Join our private community in Discord

Keep up to date by participating in our global community of data scientists and AI enthusiasts. We discuss the latest developments in data science competitions, new techniques for solving complex challenges, AI and machine learning models, and much more!