web analytics

Análisis y Disputa de Datos - Conceptos y ejemplos básicos en Python

datawrangling

[wp_ad_camp_1]

Análisis y Disputas de Datos con Python

 

Índice
  1. Data Wrangling / Disputa de Datos
    1. ¿Cuál es el propósito de la disputa de datos?
    2. Leyendo el conjunto de datos de la URL y agregando los encabezados relacionados
  2. Identificación y manejo de datos faltantes
    1. Identificando valores faltantes
    2. Contando los valores faltantes en cada columna
    3. Lidiando con datos faltantes
    4. Corrigiendo formatos de los datos
  3. Estandarización de los datos
    1. ¿Qué es la estandarización?
  4. Normalización de los datos
    1. ¿Por qué la normalización?
  5. Binning
    1. ¿Por qué binning?
    2. Visualización de los bins
  6. Indicador variable (o variable ficticia)
    1. ¿Qué es una variable indicadora?
    2. ¿Por qué usamos variables indicadoras?

Data Wrangling / Disputa de Datos

 

¿Cuál es el propósito de la disputa de datos?

Data Wrangling es el proceso de convertir datos del formato inicial a un formato que puede ser mejor para el análisis. En el siguiente ejemplo. ¿Cuál es la tasa de consumo de combustible (L / 100k) para el automóvil diesel?

Usaremos el "Automobile Data Set" del siguiente link: https://archive.ics.uci.edu/ml/machine-learning-databases/autos/imports-85.data
Estaremos usando estos datos durante los siguientes posts.

Importamos las librerias

import pandas as pd
import matplotlib.pylab as plt

Leyendo el conjunto de datos de la URL y agregando los encabezados relacionados

Asignaremos la ruta del archivo a una variable y en otra crearemos una lista con los nombres de cada columna

filename = "https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/DA0101EN/auto.csv"

headers = ["symboling","normalized-losses","make","fuel-type","aspiration", "num-of-doors","body-style",
         "drive-wheels","engine-location","wheel-base", "length","width","height","curb-weight","engine-type",
         "num-of-cylinders", "engine-size","fuel-system","bore","stroke","compression-ratio","horsepower",
         "peak-rpm","city-mpg","highway-mpg","price"]

 

[wp_ad_camp_2]

Use el método Pandas.read_csv () para cargar los datos de la dirección web. Establezca el parámetro "names" igual a la lista de Python "headers". Y posteriormente usaremos .head() para mostrar el encabezado de nuestra tabla de datos

df = pd.read_csv(filename, names = headers)
df.head()

datawrangling3

Como podemos ver, varios signos de interrogación aparecieron en el marco de datos; esos son valores faltantes que pueden dificultar nuestro análisis posterior.Entonces, ¿cómo identificamos todos esos valores perdidos y los tratamos?, ¿Cómo trabajar con datos faltantes?.

Pasos para trabajar con datos faltantes:

  • Identificar datos faltantes.
  • Lidiar con datos faltantes.
  • Formato de datos correcto.

Identificación y manejo de datos faltantes

 

Identificando valores faltantes

 

Convirtiendo "?" a NaN

En el conjunto de datos del automóvil, los datos faltantes vienen con el signo de interrogación "?". Reemplazamos "?" con NaN (No es un número), que es el marcador de valor perdido predeterminado de Python, por razones de velocidad y conveniencia computacionales. Aquí usamos la función:
.replace (A, B, inplace = True) para reemplazar A por B

[wp_ad_camp_3]

import numpy as np

# replace "?" to NaN
df.replace("?", np.nan, inplace = True)
df.head(5)

 

datawrangling4

Evaluando datos faltantes

Los valores faltantes se convierten al valor predeterminado de Python. Utilizamos las funciones integradas de Python para identificar estos valores faltantes. Hay dos métodos para detectar datos faltantes:

  1. .isnull()
  2. .notnull()

La salida es un valor booleano que indica si el valor que se pasa al argumento es de hecho datos faltantes.

missing_data = df.isnull()
missing_data.head(5)

 

datawrangling5 "True" significa valor perdido, mientras que "False" significa valor no perdido.

Contando los valores faltantes en cada columna

Usando un bucle for en Python, podemos calcular rápidamente el número de valores faltantes en cada columna. Como se mencionó anteriormente, "True" representa un valor faltante, "False" significa que el valor está presente en el conjunto de datos. En el cuerpo del bucle for, el método ".value_counts ()" cuenta el número de valores "True".

for column in missing_data.columns.values.tolist():
    print(column)
    print (missing_data[column].value_counts())
    print("")    

 

Lidiando con datos faltantes

¿Cómo lidiar con los datos faltantes?

soltar datos

    • soltar toda la fila
    • soltar toda la columna

reemplazar datos

    • reemplazarlo por medio
    • reemplazarlo por frecuencia
    • reemplazarlo en función de otras funciones

Las columnas enteras solo deben descartarse si la mayoría de las entradas de la columna están vacías. En nuestro conjunto de datos, ninguna de las columnas está lo suficientemente vacía como para caer por completo. Tenemos cierta libertad para elegir qué método reemplazar datos; sin embargo, algunos métodos pueden parecer más razonables que otros. Aplicaremos cada método a muchas columnas diferentes:

[wp_ad_camp_4]

Reemplazar por media:

  • "normalized-losses": 41 datos faltantes, reemplácelos con media.
  • "stroke": 4 datos faltantes, reemplácelos con media.
  • "bore": 4 datos faltantes, reemplácelos con media.
  • "horsepower": 2 datos faltantes, reemplácelos con media.
  • "peak-rpm": faltan 2 datos, reemplácelos con media.

Reemplazar por frecuencia:

  • "num-of-doors": faltan 2 datos, reemplácelos con "cuatro".
    • Motivo: 84% sedanes son cuatro puertas. Como las cuatro puertas son más frecuentes, es más probable que ocurran.

Suelta toda la fila:

  • "precio": 4 datos faltantes, simplemente elimine toda la fila.
    • Motivo: el precio es lo que queremos predecir. Cualquier entrada de datos sin datos de precios no se puede utilizar para la predicción; por lo tanto, cualquier fila ahora sin datos de precios no nos es útil.

 

Calculando la media de cada columna

avg_norm_loss = df["normalized-losses"].astype("float").mean(axis=0)
print("Average of normalized-losses:", avg_norm_loss)

 

Reemplazando "NaN" por la media en la columna "normalized-losses"

df["normalized-losses"].replace(np.nan, avg_norm_loss, inplace=True)

 

Calculando la media para la columna 'bore'.

avg_bore=df['bore'].astype('float').mean(axis=0)
print("Average of bore:", avg_bore)

[wp_ad_camp_1]

Reemplazando NaN por la media

df["bore"].replace(np.nan, avg_bore, inplace=True)

 

Para ver qué valores están presentes en una columna en particular, podemos usar el método ".value_counts ()":

df['num-of-doors'].value_counts()

 

El resultado es el siguiente:

four    114
two      89
Name: num-of-doors, dtype: int64

Y para seleccionar el valor máximo.

df['num-of-doors'].value_counts().idxmax()

 

El procedimiento de reemplazo es muy similar al que hemos visto anteriormente. Y  finalmente, eliminemos todas las filas que no tienen datos de precios:

df["num-of-doors"].replace(np.nan, "four", inplace=True)

# suelta la fila con NaN en la columna "price"
df.dropna(subset=["price"], axis=0, inplace=True)

# reinicia el index, porque soltamos 2 filas
df.reset_index(drop=True, inplace=True)

 

Corrigiendo formatos de los datos

El último paso en la limpieza de datos es verificar y asegurarse de que todos los datos estén en el formato correcto (int, float, text u otro).

En pandas, usamos

  • .dtype () para verificar el tipo de datos
  • .astype () para cambiar el tipo de datos

df.dtypes

Al ejecutar el comando, notaremos que  algunas columnas no son del tipo de datos correcto. Las variables numéricas deben tener el tipo 'float' o 'int', y las variables con cadenas como las categorías deben tener el tipo 'object'. Por ejemplo, las variables 'diámetro' y 'carrera' son valores numéricos que describen los motores, por lo que deberíamos esperar que sean del tipo 'flotante' o 'int'; sin embargo, se muestran como tipo 'objeto'. Tenemos que convertir los tipos de datos en un formato adecuado para cada columna utilizando el método "astype ()".

 

df[["bore", "stroke"]] = df[["bore", "stroke"]].astype("float")
df[["normalized-losses"]] = df[["normalized-losses"]].astype("int")
df[["price"]] = df[["price"]].astype("float")
df[["peak-rpm"]] = df[["peak-rpm"]].astype("float")

 

Estandarización de los datos

Los datos generalmente se recopilan de diferentes agencias con diferentes formatos. (La estandarización de datos también es un término para un tipo particular de normalización de datos, donde restamos la media y la dividimos por la desviación estándar)

¿Qué es la estandarización?

La estandarización es el proceso de transformación de datos en un formato común que permite al investigador hacer una comparación significativa.

Ejemplo

Transformar mpg a L / 100km:

En nuestro conjunto de datos, las columnas de consumo de combustible "city-mpg" y "highway-mpg" están representadas por unidad de mpg (millas por galón). Supongamos que estamos desarrollando una aplicación en un país que acepta el consumo de combustible con el estándar L / 100km

¿Necesitaremos aplicar la transformación de datos para transformar mpg en L / 100km?

La fórmula para la conversión de unidades es:

L / 100km = 235 / mpg

Podemos hacer muchas operaciones matemáticas directamente en Pandas.

df['city-L/100km'] = 235/df["city-mpg"]

 

Normalización de los datos

¿Por qué la normalización?

La normalización es el proceso de transformar valores de varias variables en un rango similar. Las normalizaciones típicas incluyen escalar la variable para que el promedio de la variable sea 0, escalar la variable para que la varianza sea 1 o escalar la variable para que los valores de la variable varíen de 0 a 1

Ejemplo

[wp_ad_camp_5]

Para demostrar la normalización, digamos que queremos escalar las columnas "lenght", "width" y "height"

Objetivo: le gustaría Normalizar esas variables para que su valor varíe de 0 a 1.

Enfoque: reemplazar el valor original por (valor original) / (valor máximo).

df['length'] = df['length']/df['length'].max()
df['width'] = df['width']/df['width'].max()

[wp_ad_camp_1]

Binning

¿Por qué binning?

Binning es un proceso de transformación de variables numéricas continuas en 'contenedores' categóricos discretos, para análisis agrupados.

Ejemplo:

En nuestro conjunto de datos, "horsepower" es una variable real valorada que va de 48 a 288, tiene 57 valores únicos. ¿Qué sucede si solo nos importa la diferencia de precio entre los automóviles con alta potencia, potencia media y poca potencia (3 tipos)? ¿Podemos reorganizarlos en tres 'contenedores' para simplificar el análisis?

Utilizaremos el método Pandas 'cut' para segmentar la columna 'horsepower' en 3 contenedores/bins.

Ejemplo de binning de datos en pandas

Primero convertiremos la columna "horsepower" al tipo de datos correctos y luego con la ayuda de la librería matplotlib graficaremos la distribución

df["horsepower"]=df["horsepower"].astype(int, copy=True)

%matplotlib inline
import matplotlib as plt
from matplotlib import pyplot
plt.pyplot.hist(df["horsepower"])

# set x/y labels and plot title
plt.pyplot.xlabel("horsepower")
plt.pyplot.ylabel("count")
plt.pyplot.title("horsepower bins")

 

horsepowerbins

Nos gustaría 3 bins de ancho de banda de igual tamaño, por lo que utilizamos el espacio de lins de numpy (start_value, end_value, numbers_generated).

Como queremos incluir el valor mínimo de caballos de fuerza, queremos establecer start_value = min (df ["horsepower"]).

Como queremos incluir el valor máximo de caballos de fuerza, queremos establecer end_value = max (df ["horsepower"]).

Como estamos construyendo 3 contenedores de igual longitud, debería haber 4 divisores, por lo que números_generados = 4.

Construimos una matriz bin, con un valor mínimo a un valor máximo, con el ancho de banda calculado anteriormente. Los contenedores serán valores utilizados para determinar cuándo termina un contenedor y comienza otro.

bins = np.linspace(min(df["horsepower"]), max(df["horsepower"]), 4)

group_names = ['Low', 'Medium', 'High']

#aplicamos la función cut
df['horsepower-binned'] = pd.cut(df['horsepower'], bins, labels=group_names, include_lowest=True )
df[['horsepower','horsepower-binned']].head(20)

 

Y procedemos nuevamente a graficar

%matplotlib inline
import matplotlib as plt
from matplotlib import pyplot
pyplot.bar(group_names, df["horsepower-binned"].value_counts())

# set x/y labels and plot title
plt.pyplot.xlabel("horsepower")
plt.pyplot.ylabel("count")
plt.pyplot.title("horsepower bins")

 

horsepowerbins2

Verifique cuidadosamente el marco de datos anterior, encontrará que la última columna proporciona los contenedores para "horsepower" con 3 categorías ("Low", "Medium" y "High").

¡Hemos reducido con éxito los intervalos de 57 a 3!

Visualización de los bins

Normalmente, se usa un histograma para visualizar la distribución de los contenedores que creamos anteriormente.

%matplotlib inline
import matplotlib as plt
from matplotlib import pyplot

a = (0,1,2)

# draw historgram of attribute "horsepower" with bins = 3
plt.pyplot.hist(df["horsepower"], bins = 3)

# set x/y labels and plot title
plt.pyplot.xlabel("horsepower")
plt.pyplot.ylabel("count")
plt.pyplot.title("horsepower bins")

horsepowerbins3

El gráfico anterior muestra el resultado de agrupación para el atributo "horsepower".

Indicador variable (o variable ficticia)

¿Qué es una variable indicadora?

Una variable indicadora (o variable ficticia) es una variable numérica utilizada para etiquetar categorías. Se llaman 'dummies' porque los números en sí mismos no tienen un significado inherente.

¿Por qué usamos variables indicadoras?

Entonces podemos usar variables categóricas para el análisis de regresión en los módulos posteriores.

Ejemplo
Vemos que la columna "fuel-type" tiene dos valores únicos, "gas" o "diesel". La regresión no entiende palabras, solo números. Para usar este atributo en el análisis de regresión, convertimos "fuel-types" en variables indicadoras.

Utilizaremos el método de panda 'get_dummies' para asignar valores numéricos a diferentes categorías de tipo de combustible.

dummy_variable_1 = pd.get_dummies(df["fuel-type"])

dummy_variable_1.rename(columns={'fuel-type-diesel':'gas', 'fuel-type-diesel':'diesel'}, inplace=True)

 

datawrangling6

 

 

 

 

 

Ahora tenemos el valor 0 para representar "gas" y 1 para representar "diesel" en la columna "fuel-type". Ahora volveremos a insertar esta columna en nuestro conjunto de datos original.

# une las tablas "df" y "dummy_variable_1" 
df = pd.concat([df, dummy_variable_1], axis=1)

# suelta la columna original "fuel-type" de "df"
df.drop("fuel-type", axis = 1, inplace=True)

 

Y por último para grabar nuestros datos ya limpios usaremos el método .to_csv()

df.to_csv('clean_df.csv')

 

Si este artículo te ayudó o tienes algunas dudas, puedes escribir un comentario  y te responderé tan pronto sea posible.

 

Te puede interesar:  Análisis estadístico descriptivo con Python / Anova, Pearson y Mapas de Calor
  1. Andersson dice:

    Antes de graficar los horsepower, se debe hacer un tratamiento para eliminar los NaN, lo demás está genial. Muchas gracias.

    1. Rubén dice:

      Claro, en la parte "lidiando con los datos faltantes" puse con qué se puede cambiar los NaN en las diferentes columnas.
      Eso queda para el lector que vaya limpiando los datos de las columnas a tratar. Tal como puse algunos ejemplos.

Deja una respuesta

Subir