Preprocesamiento de datos: Tamizaje auditivo prenatal

cleaning
tidy_data
python
preprocessing
Author

Federico Flórez

Published

August 19, 2024

Contamos con una base de datos con algunos errores en su formato, este tutorial puede servir para aquellas bases de datos que tienen problemas similares.

Como es costumbre, vamos a importar las librerías necesarias. skimpy nos sirve para limpiar el formato de los nombres de las variables y pasarlos a un formato estándar, en nuestro caso será snake case, de modo que la variable FACTORES DE RIESGO será transformada a factores_de_riesgo.

import pandas as pd
from skimpy import clean_columns
import numpy as np

Aquí fue necesario verificar el formato de encoding para evitar más contratiempos al momento de leer la base de datos, en este caso es ‘ISO-8859-1’.

import chardet
with open("tamizaje_auditivo_neonatal.csv", 'rb') as f:
    result = chardet.detect(f.read())
    print(result)
{'encoding': 'ISO-8859-1', 'confidence': 0.7284135997195934, 'language': ''}

Vamos a eliminar las primeras 5 columnas que contienen NaN, aquella que dejamos es porque contiene 2 variables que propias del oido en que se realizó el tamizaje, estas son OD y OI.

da = pd.read_csv("tamizaje_auditivo_neonatal.csv", 
                sep = ";", encoding = "ISO-8859-1", skiprows = 5)
da = da.iloc[:,:17]
da.head(13)
FECHA BASE DE DATOS DE TAMIZAJE AUDITIVO NEONATAL HORA VIA SEXO EDAD GESTACIONAL PESO NOMBRE MATERNA FACTORES DE RIESGO UBICACION TIEMPO TAMIZAJE Unnamed: 12 EVOLUCION RETAMIZAJE PROFESIONAL TELEFONO DE CONTACTO
0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN OD OI NaN NaN NaN NaN
1 4/07/2023 1/07/2023 16+05 V F 34 2440 KAREN NICOL GARZON NaN 405B 1 p P SI NaN ANDRES NUÑEZ NaN
2 4/07/2023 1/07/2023 01+22 V M 38 3100 CINTHIA SANCHEZ NaN CE/08/14 13 P P SI NaN ANDRES NUÑEZ NaN
3 4/07/2023 1/07/2023 08+38 V F 39 3120 PAOLA MORALES NaN CE/07/14 13 P P SI NaN ANDRES NÚÑEZ NaN
4 4/07/2023 1/07/2023 09+39 C F 38 3220 MARIA CAMILA PATIÑO NaN CE/07/14 13 P P SI NaN ANDRES NÚÑEZ NaN
5 4/07/2023 1/07/2023 10+30 C F 39 3360 JESSICA PIRA ACEVEDO NaN CE/14/07 13 P P SI NaN ANDRÉS NÚÑEZ NaN
6 4/07/2023 1/07/2023 16+12 C M 37 2760 JESSICA ALEXANDRA LOPEZ CASALLAS NaN NaN NaN CE CE NaN NaN NaN NaN
7 4/07/2023 1/07/2023 20+54 V M 40 3700 YEIMY LICETH PARRA BERNAL HIPOTIROIDISMO GESTACIÓN CE/14/07 13 P P SI NaN ANDRES NUÑEZ NaN
8 4/07/2023 1/07/2023 23+17 C F 40 3300 NATALIA MENDEZ LOPEZ NaN CE 4 P P SI NaN ANDRES NUÑEZ NaN
9 4/07/2023 1/07/2023 23+50 V F 37 2580 LORAINE DEL CARMEN MOLINA NaN 414 0,5 P P SI NaN ANDRES NUÑEZ NaN
10 4/07/2023 2/07/2023 09+14 C M 38 2540 NIKOLL CARDENAS VILLALOBOS NaN CE 4 P P SI NaN ANDRES NUÑEZ NaN
11 4/07/2023 2/07/2023 09+25 V M 40 3560 YEIMI PAOLA BERMUDEZ NaN CE 4 P P SI NaN ANDRES NUÑEZ NaN
12 4/07/2023 2/07/2023 10+17 V F 37 2600 YADDI ZOLORZANO OBANDO Hipertensión gestacional CE/07/14 13 P P SI NaN ANDRES NUÑEZ NaN

Ahora, para corregir los nombres de algunas variables vamos a crear una función que recorra la primera fila verificando si la observación es NaN, en el caso contrario se renombrará la variable con el valor de esta fila. Puede parecer un poco confuso, pero basta con fijarnos en las variables TAMIZAJE y Unnamed: 12, en la primera fila de cada variable se observan los datos OD y OI respectivamente. Entonces, los nombres pasaran de ser TAMIZAJE -> OD y Unnamed: 12 -> OI, tal y como se observa en la siguiente base de datos. Una vez corregimos todo, eliminamos esta fila que no aporta información.

def rename_columns(df):

    col_and_new_name = {}

    for i in range(df.shape[1]):
        if not pd.isna(df.iloc[0, i]): # Si la primera fila no es NaN
            col_and_new_name[df.columns[i]] = df.iloc[0, i] # Entonces añadir al diccionario
    
     # Renombramos las columnas con el valor de la primera fila (sub-variable)
    return df.rename(columns = col_and_new_name) # Renombramos las columnas con el valor de la primera fila (sub-variable)

da = rename_columns(da)
da = da.iloc[1:]

da.head()
FECHA BASE DE DATOS DE TAMIZAJE AUDITIVO NEONATAL HORA VIA SEXO EDAD GESTACIONAL PESO NOMBRE MATERNA FACTORES DE RIESGO UBICACION TIEMPO OD OI EVOLUCION RETAMIZAJE PROFESIONAL TELEFONO DE CONTACTO
1 4/07/2023 1/07/2023 16+05 V F 34 2440 KAREN NICOL GARZON NaN 405B 1 p P SI NaN ANDRES NUÑEZ NaN
2 4/07/2023 1/07/2023 01+22 V M 38 3100 CINTHIA SANCHEZ NaN CE/08/14 13 P P SI NaN ANDRES NUÑEZ NaN
3 4/07/2023 1/07/2023 08+38 V F 39 3120 PAOLA MORALES NaN CE/07/14 13 P P SI NaN ANDRES NÚÑEZ NaN
4 4/07/2023 1/07/2023 09+39 C F 38 3220 MARIA CAMILA PATIÑO NaN CE/07/14 13 P P SI NaN ANDRES NÚÑEZ NaN
5 4/07/2023 1/07/2023 10+30 C F 39 3360 JESSICA PIRA ACEVEDO NaN CE/14/07 13 P P SI NaN ANDRÉS NÚÑEZ NaN

Ahora sigue convertir a formato largo las variables OD y OI, para ello usamos la función melt para crear una columna llamada Oído con valores posibles OD y OI y el resultado del tamizaje será reportado en la variable Tamizaje.

id_vars = [column for column in da.columns if column not in ["OD", "OI"]]
da_melted = da.melt(id_vars=id_vars, value_vars=["OD", "OI"], var_name="Oído", value_name="Tamizaje")
da_melted.head(15)
FECHA BASE DE DATOS DE TAMIZAJE AUDITIVO NEONATAL HORA VIA SEXO EDAD GESTACIONAL PESO NOMBRE MATERNA FACTORES DE RIESGO UBICACION TIEMPO EVOLUCION RETAMIZAJE PROFESIONAL TELEFONO DE CONTACTO Oído Tamizaje
0 4/07/2023 1/07/2023 16+05 V F 34 2440 KAREN NICOL GARZON NaN 405B 1 SI NaN ANDRES NUÑEZ NaN OD p
1 4/07/2023 1/07/2023 01+22 V M 38 3100 CINTHIA SANCHEZ NaN CE/08/14 13 SI NaN ANDRES NUÑEZ NaN OD P
2 4/07/2023 1/07/2023 08+38 V F 39 3120 PAOLA MORALES NaN CE/07/14 13 SI NaN ANDRES NÚÑEZ NaN OD P
3 4/07/2023 1/07/2023 09+39 C F 38 3220 MARIA CAMILA PATIÑO NaN CE/07/14 13 SI NaN ANDRES NÚÑEZ NaN OD P
4 4/07/2023 1/07/2023 10+30 C F 39 3360 JESSICA PIRA ACEVEDO NaN CE/14/07 13 SI NaN ANDRÉS NÚÑEZ NaN OD P
5 4/07/2023 1/07/2023 16+12 C M 37 2760 JESSICA ALEXANDRA LOPEZ CASALLAS NaN NaN NaN NaN NaN NaN NaN OD CE
6 4/07/2023 1/07/2023 20+54 V M 40 3700 YEIMY LICETH PARRA BERNAL HIPOTIROIDISMO GESTACIÓN CE/14/07 13 SI NaN ANDRES NUÑEZ NaN OD P
7 4/07/2023 1/07/2023 23+17 C F 40 3300 NATALIA MENDEZ LOPEZ NaN CE 4 SI NaN ANDRES NUÑEZ NaN OD P
8 4/07/2023 1/07/2023 23+50 V F 37 2580 LORAINE DEL CARMEN MOLINA NaN 414 0,5 SI NaN ANDRES NUÑEZ NaN OD P
9 4/07/2023 2/07/2023 09+14 C M 38 2540 NIKOLL CARDENAS VILLALOBOS NaN CE 4 SI NaN ANDRES NUÑEZ NaN OD P
10 4/07/2023 2/07/2023 09+25 V M 40 3560 YEIMI PAOLA BERMUDEZ NaN CE 4 SI NaN ANDRES NUÑEZ NaN OD P
11 4/07/2023 2/07/2023 10+17 V F 37 2600 YADDI ZOLORZANO OBANDO Hipertensión gestacional CE/07/14 13 SI NaN ANDRES NUÑEZ NaN OD P
12 4/07/2023 2/07/2023 13+17 V M 39 2760 INGRID GOMEZ FRIA NaN RECUPERACION 0,5 SI NaN ANDRES NUÑEZ NaN OD P
13 4/07/2023 2/07/2023 13+49 V F 37 2960 KESHIA CARMONA DIAZ PREECLAMPSIA 409 0,5 SI NaN ANDRES NUÑEZ NaN OD P
14 4/07/2023 2/07/2023 17+47 C M 40 3600 CAROL FIERRO MOSQUERA NaN CE 4 SI NaN ANDRES NUÑEZ NaN OD P

Dado que la variable tamizaje tiene errores de registro de datos, por ejemplo la categoría p se reporta tyambién como P, P, .P, P. Si bien para nosotros es algo obvio, python lo interpreta como 5 categorías distintas. La solución es realizar una homogenización de variables.

da_melted["Tamizaje"].unique()
array(['p', 'P', 'CE', 'F', nan, 'C', 'ce', 'MICROTIA ', 'P ', 'f', '-',
       'FALLECIO ', 'REMISION', 'N', 'CE ', '.P', ' P', ' F'],
      dtype=object)
da_melted["Oído"] = da_melted["Oído"].replace({"OD": "Derecho", "OI": "Izquierdo"})
da_melted["Tamizaje"] = da_melted["Tamizaje"].str.strip().str.lower()
da_melted["Tamizaje"] = da_melted["Tamizaje"].replace({
    ".p": "p",
    "c": "ce",
    "-": np.nan,
    "n": np.nan
})
da_melted.head()
FECHA BASE DE DATOS DE TAMIZAJE AUDITIVO NEONATAL HORA VIA SEXO EDAD GESTACIONAL PESO NOMBRE MATERNA FACTORES DE RIESGO UBICACION TIEMPO EVOLUCION RETAMIZAJE PROFESIONAL TELEFONO DE CONTACTO Oído Tamizaje
0 4/07/2023 1/07/2023 16+05 V F 34 2440 KAREN NICOL GARZON NaN 405B 1 SI NaN ANDRES NUÑEZ NaN Derecho p
1 4/07/2023 1/07/2023 01+22 V M 38 3100 CINTHIA SANCHEZ NaN CE/08/14 13 SI NaN ANDRES NUÑEZ NaN Derecho p
2 4/07/2023 1/07/2023 08+38 V F 39 3120 PAOLA MORALES NaN CE/07/14 13 SI NaN ANDRES NÚÑEZ NaN Derecho p
3 4/07/2023 1/07/2023 09+39 C F 38 3220 MARIA CAMILA PATIÑO NaN CE/07/14 13 SI NaN ANDRES NÚÑEZ NaN Derecho p
4 4/07/2023 1/07/2023 10+30 C F 39 3360 JESSICA PIRA ACEVEDO NaN CE/14/07 13 SI NaN ANDRÉS NÚÑEZ NaN Derecho p
da_melted["Tamizaje"].unique()
array(['p', 'ce', 'f', nan, 'microtia', 'fallecio', 'remision'],
      dtype=object)

Ahora nos queda estandarizar el formato de los nombres de las variables, como lo explicamos al inicio.

da_melted = clean_columns(da_melted)
print(da_melted.columns)
da_melted.head(10)
Index(['fecha', 'base_de_datos_de_tamizaje_auditivo_neonatal', 'hora', 'via',
       'sexo', 'edad_gestacional', 'peso', 'nombre_materna',
       'factores_de_riesgo', 'ubicacion', 'tiempo', 'evolucion', 'retamizaje',
       'profesional', 'telefono_de_contacto', 'oido', 'tamizaje'],
      dtype='object')
fecha base_de_datos_de_tamizaje_auditivo_neonatal hora via sexo edad_gestacional peso nombre_materna factores_de_riesgo ubicacion tiempo evolucion retamizaje profesional telefono_de_contacto oido tamizaje
0 4/07/2023 1/07/2023 16+05 V F 34 2440 KAREN NICOL GARZON NaN 405B 1 SI NaN ANDRES NUÑEZ NaN Derecho p
1 4/07/2023 1/07/2023 01+22 V M 38 3100 CINTHIA SANCHEZ NaN CE/08/14 13 SI NaN ANDRES NUÑEZ NaN Derecho p
2 4/07/2023 1/07/2023 08+38 V F 39 3120 PAOLA MORALES NaN CE/07/14 13 SI NaN ANDRES NÚÑEZ NaN Derecho p
3 4/07/2023 1/07/2023 09+39 C F 38 3220 MARIA CAMILA PATIÑO NaN CE/07/14 13 SI NaN ANDRES NÚÑEZ NaN Derecho p
4 4/07/2023 1/07/2023 10+30 C F 39 3360 JESSICA PIRA ACEVEDO NaN CE/14/07 13 SI NaN ANDRÉS NÚÑEZ NaN Derecho p
5 4/07/2023 1/07/2023 16+12 C M 37 2760 JESSICA ALEXANDRA LOPEZ CASALLAS NaN NaN NaN NaN NaN NaN NaN Derecho ce
6 4/07/2023 1/07/2023 20+54 V M 40 3700 YEIMY LICETH PARRA BERNAL HIPOTIROIDISMO GESTACIÓN CE/14/07 13 SI NaN ANDRES NUÑEZ NaN Derecho p
7 4/07/2023 1/07/2023 23+17 C F 40 3300 NATALIA MENDEZ LOPEZ NaN CE 4 SI NaN ANDRES NUÑEZ NaN Derecho p
8 4/07/2023 1/07/2023 23+50 V F 37 2580 LORAINE DEL CARMEN MOLINA NaN 414 0,5 SI NaN ANDRES NUÑEZ NaN Derecho p
9 4/07/2023 2/07/2023 09+14 C M 38 2540 NIKOLL CARDENAS VILLALOBOS NaN CE 4 SI NaN ANDRES NUÑEZ NaN Derecho p

Y exportamos la nueva base de datos depurada.

da_melted.to_csv("tamiz_auditivo_neonatal.csv", index=False)