Imputación de un valor condicional

Una versión un poco más sofisticada es el reemplazo de cada valor nulo por la media, mediana o moda de aquellos valores de la característica que pertenecen a un determinado grupo. Siguiendo con el mismo ejemplo del Titanic, podríamos sustituir los valores nulos en la característica age por la media de las edades de las personas de su mismo sexo (es decir, sustituir los valores nulos de la edad de un hombre por la media de las edades de los hombres), de las personas que viajasen en su misma clase, etc.

Si quisiéramos justificar este enfoque, podríamos realizar un análisis visual de la característica en cuestión (age, en el ejemplo mencionado) desagregada según la característica categórica a usar en la imputación. Por ejemplo, podríamos mostrar la edad media de los pasajeros del Titanic en función del sexo:

age_by_sex = titanic.groupby("sex").mean(numeric_only  = True)["age"]
age_by_sex
sex
female    27.915709
male      30.726645
Name: age, dtype: float64

Comprobamos que, efectivamente, la edad media de hombres y mujeres es bastante diferente.

Para realizar esta imputación condicional, tendríamos que convertir la columna a transformar de forma que su índice coincidiese con el de la característica categórica que va a determinar el valor a imputar a cada nulo:

titanic.set_index("sex")["age"]
sex
male      22.0
female    38.0
female    26.0
female    35.0
male      35.0
          ... 
male      27.0
female    19.0
female     NaN
male      26.0
male      32.0
Name: age, Length: 891, dtype: float64

y ejecutar el método .fillna() de esta Serie Pandas pasando como argumento la estructura age_by_sex:

t = titanic.set_index("sex")["age"].fillna(age_by_sex)

Pandas alinea los índices de ambas Series antes de realizar la imputación, devolviendo el resultado que buscamos.

Podemos confirmar el resultado extrayendo una muestra del dataset original compuesta de 5 filas en las que el campo age tomase un valor nulo:

sample = titanic[titanic.age.isna()].sample(5, random_state = 1)[["sex", "age"]]
sample

Imputación de un valor condicional

y comprobando cuáles son los valores imputados:

t.iloc[sample.index]
sex
male      30.726645
male      30.726645
female    27.915709
male      30.726645
female    27.915709
Name: age, dtype: float64