import pandas as pd
from skimpy import clean_columns
import numpy as np
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.
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)