Dominando el arte de la limpieza de datos en Python - KDnuggets

Dominando el arte de la limpieza de datos en Python – KDnuggets

Nodo de origen: 2939047

Dominar el arte de la limpieza de datos en Python
Imagen del autor
 

La limpieza de datos es una parte fundamental de cualquier proceso de análisis de datos. Es el paso en el que elimina errores, maneja los datos faltantes y se asegura de que sus datos estén en un formato con el que pueda trabajar. Sin un conjunto de datos bien depurado, cualquier análisis posterior puede ser sesgado o incorrecto.

Este artículo le presenta varias técnicas clave para la limpieza de datos en Python, utilizando bibliotecas potentes como pandas, numpy, seaborn y matplotlib.

Antes de profundizar en la mecánica de la limpieza de datos, comprendamos su importancia. Los datos del mundo real suelen ser confusos. Puede contener entradas duplicadas, tipos de datos incorrectos o inconsistentes, valores faltantes, características irrelevantes y valores atípicos. Todos estos factores pueden llevar a conclusiones engañosas al analizar los datos. Esto hace que la limpieza de datos sea una parte indispensable del ciclo de vida de la ciencia de datos.

Cubriremos las siguientes tareas de limpieza de datos.
 

Dominar el arte de la limpieza de datos en Python
Imagen del autor

Antes de comenzar, importemos las bibliotecas necesarias. Usaremos pandas para la manipulación de datos y seaborn y matplotlib para visualizaciones.

También importaremos el módulo Python datetime para manipular las fechas.

import pandas as pd
import seaborn as sns
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

Primero, necesitaremos cargar nuestros datos. En este ejemplo, cargaremos un archivo CSV usando pandas. También agregamos el argumento delimitador.

df = pd.read_csv('F:KDNuggetsKDN Mastering the Art of Data Cleaning in Pythonproperty.csv', delimiter= ';')

A continuación, es importante inspeccionar los datos para comprender su estructura, con qué tipo de variables estamos trabajando y si falta algún valor. Dado que los datos que importamos no son enormes, echemos un vistazo al conjunto de datos completo.

# Look at all the rows of the dataframe
display(df)

Así es como se ve el conjunto de datos.

 

Dominar el arte de la limpieza de datos en Python
 

Puede ver inmediatamente que faltan algunos valores. Además, los formatos de fecha son inconsistentes.

Ahora, echemos un vistazo al resumen del DataFrame usando el método info().

# Get a concise summary of the dataframe
print(df.info())

Aquí está la salida del código.

 

Dominar el arte de la limpieza de datos en Python
 

Podemos ver que solo la columna pies_cuadrados no tiene ningún valor NULL, por lo que de alguna manera tendremos que manejar esto. Además, las columnas fecha_publicidad y fecha_venta son el tipo de datos del objeto, aunque debería ser una fecha.

La ubicación de la columna está completamente vacía. ¿Lo necesitamos?

Le mostraremos cómo manejar estos problemas. Comenzaremos aprendiendo cómo eliminar columnas innecesarias.

Hay dos columnas en el conjunto de datos que no necesitamos en nuestro análisis de datos, por lo que las eliminaremos.

La primera columna es comprador. No lo necesitamos, ya que el nombre del comprador no afecta el análisis.

Estamos usando el método drop() con el nombre de columna especificado. Establecemos el eje en 1 para especificar que queremos eliminar una columna. Además, el argumento inplace se establece en True para que modifiquemos el DataFrame existente y no creemos un nuevo DataFrame sin la columna eliminada.

df.drop('buyer', axis = 1, inplace = True)

La segunda columna que queremos eliminar es la ubicación. Si bien puede resultar útil tener esta información, esta es una columna completamente vacía, así que eliminémosla.

Adoptamos el mismo enfoque que con la primera columna.

df.drop('location', axis = 1, inplace = True)

Por supuesto, puedes eliminar estas dos columnas simultáneamente.

df = df.drop(['buyer', 'location'], axis=1)

Ambos enfoques devuelven el siguiente marco de datos.

 

Dominar el arte de la limpieza de datos en Python

Pueden aparecer datos duplicados en su conjunto de datos por varios motivos y pueden sesgar su análisis.

Detectemos los duplicados en nuestro conjunto de datos. Aquí se explica cómo hacerlo.

El siguiente código utiliza el método duplicado() considerar duplicados en todo el conjunto de datos. Su configuración predeterminada es considerar la primera aparición de un valor como única y las apariciones posteriores como duplicadas. Puede modificar este comportamiento utilizando el guardar parámetro. Por ejemplo, df.duplicated(keep=False) marcaría todos los duplicados como Verdaderos, incluida la primera aparición.

# Detecting duplicates
duplicates = df[df.duplicated()]
duplicates

Aquí está la salida.

 

Dominar el arte de la limpieza de datos en Python
 

La fila con el índice 3 se ha marcado como duplicada porque la fila 2 con los mismos valores es la primera vez que aparece.

Ahora necesitamos eliminar duplicados, lo cual hacemos con el siguiente código.

# Detecting duplicates
duplicates = df[df.duplicated()]
duplicates

La drop_duplicados() La función considera todas las columnas mientras identifica duplicados. Si desea considerar solo ciertas columnas, puede pasarlas como una lista a esta función de esta manera: df.drop_duplicates(subset=['columna1', 'columna2']).

 

Dominar el arte de la limpieza de datos en Python
 

Como puede ver, la fila duplicada se ha eliminado. Sin embargo, la indexación se mantuvo igual, faltando el índice 3. Arreglaremos esto restableciendo los índices.

df = df.reset_index(drop=True)

Esta tarea se realiza utilizando el restablecer_índice() función. El argumento drop=True se utiliza para descartar el índice original. Si no incluye este argumento, el índice anterior se agregará como una nueva columna en su DataFrame. Al configurar drop=True, le estás diciendo a los pandas que olviden el índice anterior y lo restablezcan al índice entero predeterminado.

Para practicar, intenta eliminar duplicados de este conjunto de datos de Microsoft.

A veces, los tipos de datos pueden estar configurados incorrectamente. Por ejemplo, una columna de fecha podría interpretarse como cadenas. Debe convertirlos a sus tipos apropiados.

En nuestro conjunto de datos, haremos esto para las columnas fecha_publicidad y fecha_venta, ya que se muestran como el tipo de datos del objeto. Además, las fechas tienen un formato diferente en las filas. Necesitamos hacerlo consistente, además de convertirlo a la fecha.

La forma más fácil es usar el hasta_fechahora() método. Nuevamente, puede hacerlo columna por columna, como se muestra a continuación.

Al hacer eso, configuramos el argumento del primer día en Verdadero porque algunas fechas comienzan con el día primero.

# Converting advertisement_date column to datetime
df['advertisement_date'] = pd.to_datetime(df['advertisement_date'], dayfirst = True) # Converting sale_date column to datetime
df['sale_date'] = pd.to_datetime(df['sale_date'], dayfirst = True)

También puede convertir ambas columnas al mismo tiempo usando el aplicar() método con hasta_fechahora().

# Converting advertisement_date and sale_date columns to datetime
df[['advertisement_date', 'sale_date']] = df[['advertisement_date', 'sale_date']].apply(pd.to_datetime, dayfirst = True)

Ambos enfoques te dan el mismo resultado.

 

Dominar el arte de la limpieza de datos en Python
 

Ahora las fechas tienen un formato consistente. Vemos que no todos los datos se han convertido. Hay un valor NaT en fecha_anuncio y dos en fecha_venta. Esto significa que falta la fecha.

Comprobemos si las columnas se convierten a fechas usando el info () método.

# Get a concise summary of the dataframe
print(df.info())

 

Dominar el arte de la limpieza de datos en Python
 

Como puede ver, ambas columnas no están en formato datetime64[ns].

Ahora, intenta convertir los datos de TEXTO a NUMÉRICOS en este Conjunto de datos de Airbnb.

A los conjuntos de datos del mundo real a menudo les faltan valores. Manejar los datos faltantes es vital, ya que ciertos algoritmos no pueden manejar dichos valores.

A nuestro ejemplo también le faltan algunos valores, así que echemos un vistazo a los dos enfoques más habituales para manejar datos faltantes.

Eliminar filas con valores faltantes

Si el número de filas con datos faltantes es insignificante en comparación con el número total de observaciones, podría considerar eliminar estas filas.

En nuestro ejemplo, la última fila no tiene valores excepto los pies cuadrados y la fecha del anuncio. No podemos usar esos datos, así que eliminemos esta fila.

Aquí está el código donde indicamos el índice de la fila.

df = df.drop(8)

El DataFrame ahora se ve así.

 

Dominar el arte de la limpieza de datos en Python
 

La última fila se eliminó y nuestro DataFrame ahora se ve mejor. Sin embargo, todavía faltan algunos datos que manejaremos utilizando otro enfoque.

Imputar valores faltantes

Si le faltan datos importantes, una mejor estrategia que eliminarlos podría ser la imputación. Este proceso implica completar los valores faltantes en función de otros datos. Para datos numéricos, los métodos de imputación comunes implican el uso de una medida de tendencia central (media, mediana, moda).

En nuestro DataFrame ya modificado, tenemos valores NaT (Not a Time) en las columnas fecha_publicidad y fecha_venta. Imputaremos estos valores faltantes usando el media() método.

El código usa el relleno () Método para encontrar y llenar los valores nulos con el valor medio.

# Imputing values for numerical columns
df['advertisement_date'] = df['advertisement_date'].fillna(df['advertisement_date'].mean())
df['sale_date'] = df['sale_date'].fillna(df['sale_date'].mean())

También puedes hacer lo mismo en una línea de código. Usamos el aplicar() para aplicar la función definida usando lambda. Igual que arriba, esta función utiliza el relleno () y media() métodos para completar los valores faltantes.

# Imputing values for multiple numerical columns
df[['advertisement_date', 'sale_date']] = df[['advertisement_date', 'sale_date']].apply(lambda x: x.fillna(x.mean()))

El resultado en ambos casos se ve así.

 

Dominar el arte de la limpieza de datos en Python
 

Nuestra columna sale_date ahora tiene horas que no necesitamos. Eliminémoslos.

Usaremos el strftime () método, que convierte las fechas a su representación de cadena y un formato específico.

df['sale_date'] = df['sale_date'].dt.strftime('%Y-%m-%d')

 

Dominar el arte de la limpieza de datos en Python
 

Las fechas ahora parecen todas ordenadas.

Si necesitas usar strftime () en varias columnas, puede volver a utilizar lambda de la siguiente manera.

df[['date1_formatted', 'date2_formatted']] = df[['date1', 'date2']].apply(lambda x: x.dt.strftime('%Y-%m-%d'))

Ahora veamos cómo podemos imputar valores categóricos faltantes.

Los datos categóricos son un tipo de datos que se utilizan para agrupar información con características similares. Cada uno de estos grupos es una categoría. Los datos categóricos pueden tomar valores numéricos (como "1" indica "masculino" y "2" indica "femenino"), pero esos números no tienen significado matemático. No puedes sumarlos, por ejemplo.

Los datos categóricos normalmente se dividen en dos categorías:

  1. Datos nominales: Esto ocurre cuando las categorías sólo están etiquetadas y no se pueden organizar en ningún orden en particular. Los ejemplos incluyen género (masculino, femenino), tipo de sangre (A, B, AB, O) o color (rojo, verde, azul).
  1. Datos ordinales: Aquí es cuando se pueden ordenar o clasificar las categorías. Si bien los intervalos entre las categorías no están igualmente espaciados, el orden de las categorías tiene un significado. Los ejemplos incluyen escalas de calificación (calificación de 1 a 5 de una película), un nivel educativo (escuela secundaria, licenciatura, posgrado) o etapas del cáncer (Etapa I, Etapa II, Etapa III).

Para imputar datos categóricos faltantes, normalmente se utiliza la moda. En nuestro ejemplo, la columna property_category son datos categóricos (nominales) y faltan datos en dos filas.

Reemplacemos los valores faltantes con moda.

# For categorical columns
df['property_category'] = df['property_category'].fillna(df['property_category'].mode()[0])

Este código usa el relleno () función para reemplazar todos los valores NaN en la columna property_category. Lo reemplaza con modo.

Además, la parte [0] se utiliza para extraer el primer valor de esta Serie. Si hay varios modos, esto seleccionará el primero. Si sólo hay un modo, todavía funciona bien.

Aquí está la salida.

 

Dominar el arte de la limpieza de datos en Python
 

Los datos ahora parecen bastante buenos. Lo único que queda es ver si hay valores atípicos.

Puedes practicar cómo lidiar con valores nulos en este Pregunta de la meta entrevista, donde tendrás que reemplazar los NULL con ceros.

Los valores atípicos son puntos de datos en un conjunto de datos que son claramente diferentes de las otras observaciones. Es posible que se encuentren excepcionalmente alejados de los demás valores del conjunto de datos, fuera de un patrón general. Se consideran inusuales debido a que sus valores son significativamente mayores o menores en comparación con el resto de los datos.

Los valores atípicos pueden surgir debido a varias razones, tales como:

  • Errores de medición o entrada
  • Corrupción de datos
  • Verdaderas anomalías estadísticas

Los valores atípicos pueden afectar significativamente los resultados de su análisis de datos y modelado estadístico. Pueden dar lugar a una distribución sesgada, sesgo o invalidar los supuestos estadísticos subyacentes, distorsionar el ajuste estimado del modelo, reducir la precisión predictiva de los modelos predictivos y conducir a conclusiones incorrectas.

Algunos métodos comúnmente utilizados para detectar valores atípicos son la puntuación Z, el IQR (rango intercuartil), los diagramas de caja, los diagramas de dispersión y las técnicas de visualización de datos. En algunos casos avanzados, también se utilizan métodos de aprendizaje automático.

La visualización de datos puede ayudar a identificar valores atípicos. El diagrama de caja de Seaborn es útil para esto.

plt.figure(figsize=(10, 6))
sns.boxplot(data=df[['advertised_price', 'sale_price']])

Usamos plt.figure() para establecer el ancho y alto de la figura en pulgadas.

Luego creamos el diagrama de caja para las columnas precio_publicado y precio_venta, que se ve así.

 

Dominar el arte de la limpieza de datos en Python
 

La trama se puede mejorar para facilitar su uso agregando esto al código anterior.

plt.xlabel('Prices')
plt.ylabel('USD')
plt.ticklabel_format(style='plain', axis='y')
formatter = ticker.FuncFormatter(lambda x, p: format(x, ',.2f'))
plt.gca().yaxis.set_major_formatter(formatter)

Usamos el código anterior para configurar las etiquetas para ambos ejes. También notamos que los valores en el eje y están en notación científica y no podemos usarlos para los valores de precios. Entonces cambiamos esto a un estilo simple usando la función plt.ticklabel_format().

Luego creamos el formateador que mostrará los valores en el eje y con comas como separadores de miles y puntos decimales. La última línea de código aplica esto al eje.

La salida ahora se ve así.

 

Dominar el arte de la limpieza de datos en Python
 

Ahora bien, ¿cómo identificamos y eliminamos el valor atípico?

Una de las formas es utilizar el método IQR.

IQR, o rango intercuartil, es un método estadístico que se utiliza para medir la variabilidad dividiendo un conjunto de datos en cuartiles. Los cuartiles dividen un conjunto de datos ordenados por rango en cuatro partes iguales, y los valores dentro del rango del primer cuartil (percentil 25) y el tercer cuartil (percentil 75) forman el rango intercuartil.

El rango intercuartil se utiliza para identificar valores atípicos en los datos. Así es como funciona:

  1. Primero, calcule el primer cuartil (Q1), el tercer cuartil (Q3) y luego determine el IQR. El IQR se calcula como Q3 – Q1.
  2. Cualquier valor inferior a Q1 – 1.5IQR o superior a Q3 + 1.5IQR se considera un valor atípico.

En nuestro diagrama de caja, el cuadro en realidad representa el IQR. La línea dentro del cuadro es la mediana (o segundo cuartil). Los "bigotes" del diagrama de caja representan el rango dentro de 1.5*IQR del primer y tercer trimestre.

Cualquier punto de datos fuera de estos bigotes puede considerarse atípico. En nuestro caso, es el valor de $12,000,000. Si observa el diagrama de caja, verá con qué claridad se representa esto, lo que muestra por qué la visualización de datos es importante para detectar valores atípicos.

Ahora, eliminemos los valores atípicos utilizando el método IQR en código Python. Primero, eliminaremos los valores atípicos de precios anunciados.

Q1 = df['advertised_price'].quantile(0.25)
Q3 = df['advertised_price'].quantile(0.75)
IQR = Q3 - Q1
df = df[~((df['advertised_price'] (Q1 - 1.5 * IQR)) |(df['advertised_price'] > (Q3 + 1.5 * IQR)))]

Primero calculamos el primer cuartil (o el percentil 25) usando el cuantil() función. Hacemos lo mismo para el tercer cuartil o el percentil 75.

Muestran los valores por debajo de los cuales caen el 25% y el 75% de los datos, respectivamente.

Luego calculamos la diferencia entre los cuartiles. Hasta ahora, todo es simplemente traducir los pasos IQR al código Python.

Como paso final, eliminamos los valores atípicos. En otras palabras, todos los datos inferiores a Q1 – 1.5 * IQR o superiores a Q3 + 1.5 * IQR.

El operador '~' niega la condición, por lo que solo nos quedan los datos que no son valores atípicos.

Luego podemos hacer lo mismo con el precio de venta.

Q1 = df['sale_price'].quantile(0.25)
Q3 = df['sale_price'].quantile(0.75)
IQR = Q3 - Q1
df = df[~((df['sale_price'] (Q1 - 1.5 * IQR)) |(df['sale_price'] > (Q3 + 1.5 * IQR)))]

Por supuesto, puedes hacerlo de una manera más concisa usando el en bucle.

for column in ['advertised_price', 'sale_price']: Q1 = df[column].quantile(0.25) Q3 = df[column].quantile(0.75) IQR = Q3 - Q1 df = df[~((df[column] (Q1 - 1.5 * IQR)) |(df[column] > (Q3 + 1.5 * IQR)))]

El bucle itera de las dos columnas. Para cada columna, calcula el IQR y luego elimina las filas en el DataFrame.

Tenga en cuenta que esta operación se realiza de forma secuencial, primero para el precio_publicado y luego para el precio_venta. Como resultado, el DataFrame se modifica in situ para cada columna y las filas se pueden eliminar por ser un valor atípico en cualquiera de las columnas. Por lo tanto, esta operación podría generar menos filas que si los valores atípicos de precio_publicado y precio_de_venta se eliminaran de forma independiente y los resultados se combinaran posteriormente.

En nuestro ejemplo, el resultado será el mismo en ambos casos. Para ver cómo cambió el diagrama de caja, debemos trazarlo nuevamente usando el mismo código que antes.

plt.figure(figsize=(10, 6))
sns.boxplot(data=df[['advertised_price', 'sale_price']])
plt.xlabel('Prices')
plt.ylabel('USD')
plt.ticklabel_format(style='plain', axis='y')
formatter = ticker.FuncFormatter(lambda x, p: format(x, ',.2f'))
plt.gca().yaxis.set_major_formatter(formatter)

Aquí está la salida.

 

Dominar el arte de la limpieza de datos en Python
 

Puedes practicar el cálculo de percentiles en Python resolviendo el Pregunta de la entrevista de la Asamblea General.

La limpieza de datos es un paso crucial en el proceso de análisis de datos. Aunque puede llevar mucho tiempo, es esencial garantizar la exactitud de los hallazgos.

Afortunadamente, el rico ecosistema de bibliotecas de Python hace que este proceso sea más manejable. Aprendimos cómo eliminar filas y columnas innecesarias, reformatear datos y lidiar con valores faltantes y valores atípicos. Estos son los pasos habituales que se deben realizar con la mayoría de los datos. Sin embargo, a veces también necesitarás combinar dos columnas en una, verificar los datos existentes, asignarle etiquetaso deshacerse de los espacios en blanco.

Todo esto es limpieza de datos, ya que le permite convertir datos confusos del mundo real en un conjunto de datos bien estructurado que puede analizar con confianza. Simplemente compare el conjunto de datos con el que comenzamos con el que terminamos.

Si no ves la satisfacción en este resultado y los datos limpios no te emocionan extrañamente, ¿qué estás haciendo en el mundo en ciencia de datos?
 

Nate Rosidi es científico de datos y en estrategia de producto. También es profesor adjunto de enseñanza de análisis y es el fundador de StrataScratch, una plataforma que ayuda a los científicos de datos a prepararse para sus entrevistas con preguntas de entrevistas reales de las principales empresas. Conéctate con él en Gorjeo: StrataScratch or Etiqueta LinkedIn.

Sello de tiempo:

Mas de nuggets