No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

14 Días
12 Hrs
41 Min
1 Seg

Imputación por llenado hacia atrás y hacia adelante

10/17
Recursos

Aportes 21

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Le embocamos un apply y listo el polio

(
    nhanes_df
    .select_columns("height", "weight", "gender", "diabetes", "general_health_condition")
    .sort_values(
        by=['gender','diabetes','general_health_condition','weight'],
        ascending=True
    )
    .groupby(["gender", "general_health_condition"], dropna=False)
    .apply(lambda x: x.ffill())
)

Imputacion dentro de Dominios

Para que la imputacion tenga mas sentido debemos considerar las variables categoricas. Podemos tratar las variables categoricas como dominios donde nuestra variable de interes toma solo valores dentro del mismo. Es decir, en cada categoria puede existir un rango distinto de valores para la variable de interes. Por lo tanto, haciendo imputaciones dentro de los dominios puedes conservar la estructura de los datos y las relaciones entre las variables.

Ejemplo de imputacion dentro de dominios

  • Para este caso, la variable a la que se va a imputar los datos faltantes es a weight
(
    nhanes_df
    # seleccionamos las variables. Hay dos categoricas y tres numericas
    .select_columns('weight', 'height', 'gender', 'diabetes', 'general_health_condition')
    # ordenamos los grupos segun nuestro interes 
    # para este caso, primero el genero, seguido de diabetes, su estado de salud y finalmente la altura
    .sort_values(
        by = ['gender', 'diabetes', 'general_health_condition', 'height'],
        ascending = True
    )# realizamos la imputacion con el metodo transform
    .transform_column(
        'weight',   # variable de interes
        lambda x: x.ffill(),    # imputacion hacia adelante
        elementwise = False     # pasa una serie y no un unico valor
    )
)

De esta manera estamos garantizando que la imputacion esta tomando valores adecuados para cada dominio. Sin embargo, puede ocurrir que al traerse el valor antecesor se obtenga un valor de otro dominio generando ruido en los datos. Para ello se utiliza la funcion groupby lo cual permite agrupar los datos por las variables categoricas y luego ordenarlos por las variables numericas para asi realizar la imputacion y evitar este problema.

2. Imputacion por llenado hacia atras y hacia adelante (Hot Deck y Cold Deck)

Consiste en sustituir los valores faltantes con valores completos que estan antes o despues.

Ventajas

  • Rapido y facil de implementar
  • Los datos imputados no son constantes, van a depender de los valores alrededor (arriba, abajo, a la derecha o a la izquierda).
  • Existen trucos para evitar romper las relaciones entre variables.

Desventajas

  • Las relaciones multivariables pueden ser distorsionadas

Muy útil la recomendación a la hora de hacer la imputación hacia adelante organizar por datos o grupos similares, de esta manera los datos reemplazados se parecen a sus semejantes.

Un “dominio” se refiere a un grupo específico de observaciones dentro de tus datos que comparten ciertas características o propiedades en común. Estas características pueden ser variables categóricas o cualquier otro criterio que defina una agrupación lógica de datos.

Ejemplo de Imputacion por llenado hacia atras

(
    nhanes_df   # dataframe
    .select_columns('height', 'weight') # variables numericas
    .fillna(method = 'bfill')
)
  • Metodo alternativo con Pandas. Llenado hacia atras
# metodo alternativo de Pandas. Llenado hacia atras

(
    nhanes_df                           # dataframe
    .select_columns('height', 'weight') # variables numericas
    #.fillna(method = 'bfill')
    .bfill()                            # metodos de Pandas
)

Ejemplo de Imputacion por llenado hacia adelante

# los valores faltantes se sustituyen por el valor antecesor

(
    nhanes_df   # dataframe
    .select_columns('height', 'weight') # variables numericas
    .fillna(method = 'ffill')
)
  • Metodo alternativo con Pandas. Llenado hacia adelante
(
    nhanes_df                           # dataframe
    .select_columns('height', 'weight') # variables numericas
    #.fillna(method = 'ffill')
    .ffill()                            # metodos de Pandas
)

Imputación por llenado hacia atrás y hacia adelante

 

Definición:

 
La imputación por llenado hacia atrás y hacia adelante, también conocida como Hot Deck y Cold Deck, es un método simple para imputar valores faltantes en una serie de datos. Consiste en reemplazar los valores faltantes con valores completos que se encuentran antes o después dentro de la misma columna.

Tipos de Imputación por llenado:

  • Imputación por llenado hacia atrás (Hot Deck): Se reemplaza el valor faltante por el valor completo más cercano que se encuentra antes de él en la misma columna.
  • Imputación por llenado hacia adelante (Cold Deck): Se reemplaza el valor faltante por el valor completo más cercano que se encuentra después de él en la misma columna.

 
Ventajas:

 

  • Simple y rápido de implementar.
  • Preserva la distribución original de la variable.
  • No requiere entrenamiento de modelos.

 
Desventajas:

 

  • Puede introducir sesgo en los datos si los valores no se distribuyen uniformemente.
  • No tiene en cuenta las relaciones entre variables.
  • Puede ser impreciso para series de datos con patrones complejos.

 
Cuándo usar la imputación por llenado:

 

  • Cuando el conjunto de datos tiene una pequeña cantidad de valores faltantes.
  • Cuando la distribución de la variable es uniforme.
  • Cuando se requiere un método simple y rápido de imputación.

 
Alternativas a la imputación por llenado:

 

  • Imputación por media, mediana o moda: Reemplaza el valor faltante por la media, mediana o moda de la variable.
  • Imputación por regresión: Se utiliza un modelo de regresión para predecir el valor faltante.
  • Imputación por MICE (Multiple Imputation by Chained Equations): Se utiliza un conjunto de modelos para imputar los valores faltantes.

Mi soloucion al reto

Ordeno por altura y luego por peso porque creo que el peso depende mas de la altura, agrupo por los los datos categoricos manteniendo los nulos, le aplico forward-fill a las columnas de altura y peso.

(
    nhanes_df
    .select_columns('height', 'weight', 'gender', 'diabetes', 'general_health_condition')
    .sort_values(by=['height', 'weight'], ascending=True)
    .groupby(
        by=['gender', 'diabetes', 'general_health_condition'],
        dropna=False,
    )
    .apply(lambda df: df[['height', 'weight']].ffill())
    .reset_index()
)


Esta sera la resolucion al reto? creo falto un poquito de claridad sobre lo que se buscaba, o sere yo muy noob.

Yo entendi qee habia que agrupar por las variables categoricas que son genero y condicion general de salud.

Y alli si aplicar el transform_column().

(
    nhanes_df
    .select_columns("height", "weight", "gender", "diabetes", "general_health_condition")
    .groupby(["gender", "general_health_condition"], dropna=False).value_counts(dropna=False)
    .reset_index()
    .transform_column(
        "weight",
        lambda x: x.bfill(),
        elementwise = False
    )
    .transform_column(
        "height",
        lambda x: x.bfill(),
        elementwise = False
    )
    .head(20)
)
Me dieron estos resultados. * raw = nhanes\_df * sorted = el de la clase * grouped\_sorted = el del reto * comment = el df del comentario con mas visibilidad ![](https://static.platzi.com/media/user_upload/Screenshot%202024-10-22%20at%209.49.04PM-3fb3b8d9-ffc3-47a8-9aa5-9febecda1e80.jpg) Así hice el reto: ```js ( nhanes_df[['height', 'weight', 'gender', 'diabetes','general_health_condition']] .groupby( ['gender', 'general_health_condition'], dropna=False, ).apply(lambda df: df.sort_values( by=['diabetes', 'height'], ascending=True, ).transform_column( 'weight', lambda serie: serie.ffill(), elementwise=False )) ) ```( nhanes\_df\[\['height', 'weight', 'gender', 'diabetes','general\_health\_condition']] .groupby( \['gender', 'general\_health\_condition'], dropna=False, ).apply(lambda df: df.sort\_values( by=\['diabetes', 'height'], ascending=True, ).transform\_column( 'weight', lambda serie: serie.ffill(), elementwise=False )))
Dejo mi aporte y la manera en la que entendí esta clase. **Importancia de ordenar las columnas antes de imputar** ![](https://static.platzi.com/media/user_upload/image-14ff9767-a979-433c-97ee-22237a0c099c.jpg) 1. **<u>Imputación general con ordenación:</u>** ![](https://static.platzi.com/media/user_upload/image-17e7a72e-d9a1-4b0b-a88e-a9a07de3b697.jpg) 1. **<u>Imputación dentro de dominios o subconjuntos:</u>** ![](https://static.platzi.com/media/user_upload/image-14c24480-fc7a-478c-bc51-24e4d48aeeb2.jpg)
```python ( nhanes_df .select_columns("height", "weight", "gender", "diabetes", "general_health_condition") .sort_values( by = ["gender", "diabetes", "general_health_condition", "weight"], ascending = True ) .groupby(["gender", "general_health_condition"], dropna=False) .apply(lambda x:x.ffill()) ) ```(    nhanes\_df    .select\_columns("height", "weight", "gender", "diabetes", "general\_health\_condition")    .sort\_values(        by = \["gender", "diabetes", "general\_health\_condition", "weight"],        ascending = True    )    .groupby(\["gender", "general\_health\_condition"], dropna=False)    .apply(lambda x:x.ffill())    )
```js ( nhanes_df .select_columns(["height_inches", "weight_pounds","gender","diabetes","health_condition"]) .sort_values( by = ["gender","diabetes","health_condition","height_inches"], ascending = True ) .groupby(["diabetes","gender","health_condition"],dropna = False) .apply(lambda x: x.ffill()) ) ```(    nhanes\_df    .select\_columns(\["height\_inches", "weight\_pounds","gender","diabetes","health\_condition"])    .sort\_values(        by = \["gender","diabetes","health\_condition","height\_inches"],        ascending = True    )    .groupby(\["diabetes","gender","health\_condition"],dropna = False)    .apply(lambda x: x.ffill()))
Hay que tener en cuenta que, si hacemos groupby y luego aplicamos ffill o bfill, en los grupos, muchas veces al inicio o al final no habrá ningún dato para extender y lo dejará nulo. Por ejemplo. Si resolvemos el reto mediante un apply: ```js ( nhanes_df .select_columns('height', 'weight', 'gender', 'diabetes', 'general_health_condition') .sort_values( by=['gender', 'diabetes', 'general_health_condition','height'], ascending=True ) .groupby(['gender', 'general_health_condition', 'height'], group_keys=True, dropna=False ) .apply( lambda df: df['weight'].ffill() ) .reset_index() .isna().sum() ) ``` Retorna que quedaron 249 valores nulos gender 0 general\_health\_condition 1360 height 1669 SEQN 0 weight 249 dtype: int64 Si usamos transform: ```js # Seleccionar las columnas de interés y ordenar df_modificado = ( nhanes_df .select_columns('height', 'weight', 'gender', 'diabetes', 'general_health_condition') .sort_values(by=['gender', 'diabetes', 'general_health_condition', 'height'], ascending=True) ) # Realizar la imputación. Importante: Aplicamos 'transform' directamente sobre la columna 'weight'. df_modificado['weight'] = ( df_modificado .groupby(['gender', 'general_health_condition', 'height'], group_keys=True, dropna=False)['weight'] .transform(lambda x: x.ffill()) ) # Resetear el índice si es necesario y calcular los valores faltantes df_modificado = df_modificado.reset_index(drop=True) print(df_modificado.isna().sum()) ``` Queda igual height 1669 weight 249 gender 0 diabetes 0 general\_health\_condition 1360 dtype: int64 Y si hacemos ffill().bfill() encadenado porque hay un grupo completo de nulos, quedan 2 sin imputar height 1669 weight 2 gender 0 diabetes 0 general\_health\_condition 1360 dtype: int64

Es opción no resultó mejor que las anteriores:

Efectivamente necesitamos un poco más de info para resolver el problema. Recurrí a ChatGPT para un poco más de luz, he aquí el código para lo más cercano que pude de lo que pedía el profesor:

(
    nhanes_df
    .select_columns('height', 'weight', 'gender', 'diabetes', 'general_health_condition')
    .groupby(
        [
            'gender',
            'diabetes',
            'general_health_condition',
            'height'
            # 'weight'
        ],
        dropna=False,
        as_index=False
        )
    # .apply(lambda df: df.sort_values('weight').ffill())

    .apply(lambda df: df.sort_values(['weight']).ffill())
    # .reset_index(drop=True)
    # .query('weight.isna()')
    # .loc[730:740].head(35)
    # .transform_column(
    #     'weight',
    #     lambda x: x.fillna(method='ffill'),
    #     elementwise=False
    #     )
    
)

No entendi muy bien el reto porque al aplicar un groupby lo que hago es eliminar o agrupar las observaciones duplicadas y cambiara completamente los resultados, en fin cumpliendo con el reto esta es mi solucion

(
    nhanes_df
    .select_columns('height','weight','gender','diabetes','general_health_condition')
    .groupby(['gender','diabetes','general_health_condition','height','weight'], as_index=False, dropna=False).sum()
    .pipe(
        lambda df: (df.sort_values(
            by=['gender','diabetes','general_health_condition','height'],
            ascending=True
            )
            .transform_columns(
                ['weight','height','general_health_condition'],
                lambda x: x.ffill(),
                elementwise=False
            )
        )
    )
)