No tienes acceso a esta clase

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

¿Cómo trabajar con datos faltantes?

27/38
Recursos

Los datos faltantes representan un verdadero problema sobre todo cuando estamos realizando agregaciones. Imagina que tenemos datos faltantes y los llenamos con 0, pero eso haría que la distribución de datos se modificaría radicalmente. Podemos eliminar los registros, pero la fuerza de nuestras conclusiones se debilita.

Pandas nos otorga varias funcionalidades para identificarlas y para trabajar con ellas. Existe el concepto que se llama NaN, cuando existe un dato faltante simplemente se rellena con un NaN y en ese momento podemos preguntar cuáles son los datos faltantes con .isna().

  • notna() para preguntar dónde hay datos completos.
  • dropna() para eliminar el registro.

Para reemplazar:

  • fillna() donde le damos un dato centinela
  • ffill() donde utiliza el último valor.

Aportes 48

Preguntas 5

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Podemos agregar al final un

.applymap(lambda final_title: final_title.capitalize())

Para mantener la mayúscula como en los demás titulos

(sin acentos)

Hacer SPLIT y luego un JOIN con el string vacio me parece que esta de mas.
Otra solucion es emplear REPLACE en vez del SPLIT y JOIN
(creo que es mas eficiente en tiempo de ejecucion pero habria que saber como Python tiene implementada la funcion REPLACE)

Les dejo el codigo:

missing_titles2 = (el_universal[missing_titles_mask]['url']
                     .str.extract(r'(?P<missing_titles>[^/]+)$')
                     .applymap(lambda title: title.replace('-',' ')))
missing_titles2```

En caso que por alguna razón les aparezca el error:
‘float’ object has no attribute 'split’
deben convertir por medio de applymap todo el contenido a “str” con:
.applymap(str)

missing_titles=(el_universal[missing_titles_mask]['url']
            .str.extract(r'(?P<missing_titles>[^/]+)$')
            .applymap(str)
            .applymap(lambda title: title.split('-'))
            .applymap(lambda title_word_list: ' '.join(title_word_list))
        )
missing_titles

Para probar expresiones regulares se puede usar:

https://regex101.com/

Se ingresa el ejemplo de prueba en la sección “TEST STRING”, y luego se inician las pruebas de la expresión regular en la sección “REGULAR EXPRESSION”, a medida que se escribe la regex se va seleccionando la parte del texto que sería retornada.

Adicionalmente, se tienen explicaciones sobre las regex en la parte inferior de la ventana principal del sitio (regex101.com).

una alternativa a la rutina split sería la rutina replace(’-’,’ ') que de entrada reemplazaría los guiones por espacios.

  • applymap() method only works on a pandas dataframe where function is applied on every element individually.

  • apply() method can be applied both to series and dataframes where function can be applied both series and individual elements based on the type of function provided.

  • map() method only works on a pandas series where type of operation to be applied depends on argument passed as a function, dictionary or a list.

Tambien pude limpiar los datos asi:

missing_title_mask = eluniversal['title'].isna()
(eluniversal[missing_title_mask]['url']
     .str.extract(r'(?P<missing_titles>[^/]+)$')
     .applymap(lambda newtitle: newtitle.replace('-', ' '))
)

Este video y el anterior estan cruzados, primero va este y luego el anterior.

Tendre que hacer ese curso de expresiones regulares, veo que es muy importante 😄

Creo que es mas zen utilizar la funcion replace y genera un codigo mas limpio.-

Que alguien me corrija pero no era mas facil, en ves de realizar applymap dos veces, simplemente poner .replace(’-’, ’ ')

Creo que en vez de los dos lambda se pudo haber usado .replace()

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.replace.html

.replace('-', ' ')

For DataFrame:

  • apply(): It is used when you want to apply a function along the row or column. axis = 0 for column and axis = 1 for row.
  • applymap(): It is used for element-wise operation across the whole DataFrame.

For Series:

  • apply(): It is used when you want to apply a function on the values of Series.
  • map(): It is used to substitute each value with another value.

Ref. https://towardsdatascience.com/introduction-to-pandas-apply-applymap-and-map-5d3e044e93ff

Este curso deberia estar dentro de la carrera de IA

Para ignenieria de datos es necesario hacer todo ello?
Para obtener la cadena despues del ultimo “/” yo hubiera dividido la url con split, por cada “/”, luego obtener el último valor de la lista. A este valor solo usar .replace("-", " ")
Y así reemplazar todos los guiones por espacios.

Para que sea más lindo hice una tercera trasnformación:

missing_titles = (el_universal[missing_titles_mask]['url']
                     .str.extract(r'(?P<missing_titles>[^/]+)$')
                     .applymap(lambda title: title.split('-'))
                     .applymap(lambda title_word_list: ' '.join(title_word_list))
                     .applymap(lambda title: title.capitalize()))

Con la última línea logro que todos los títulos comiencen con mayúscula

Excelente clase.

#3. Rellenar datos faltantes

missing_titles_mask = el_universal['title'].isna()

missing_titles_mask

missing_titles = (el_universal[missing_titles_mask]['url']
                 .str.extract(r'(?P<missing_titles>[^/]+)$')
                 .applymap(lambda title: title.split('-'))
                 .applymap(lambda title_word_list: ' '.join(title_word_list))
                  )
missing_titles```

me gustaría saber cual es el curso de platzi de expresiones regulares.

UN MUNDOO IDEAAAAL
UN MUNDO EN EL QUE TUUU Y YO
PODAMOS DECIDIR
COMO VIVIR
SIN NADIE QUE LO IMPIDAA

missing_titles = (el_universal[missing_tittles_mask]['url']
                    .str.extract(r'(?P<missing_tittles>[^/]+)$')
                    .applymap(lambda title: title.split('-'))
                    .applymap(lambda title_word_list: ' '.join(title_word_list))
                 )

missing_titles


¿Cuál es la diferencia entre usar apply y applymap en el dataframe?

De donde saca esa variable: title word list?? (para despues unirla con el ultimo apply?? esa variable no se creo en ningun lugar antes

Excelente clase

que significan los datos que dicen box???

fue mas tedioso usar split, era mejor usar replace("-", " ") y listo asi de facil ya transformamos el titulo

Completamos los títulos, muy bien.

Me esta generando el siguiente error

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-23-16b6be88d3a3> in <module>
      5 missing_titles = (el_universal[missing_titles_mask]['url']
      6                       .str.extract(r'(?P<missing_titles>[^/]+)$')
----> 7                       .applymap(lambda title: title.split('-'))
      8                       .applymap(lambda title_word_list: ' '.join(title_word_list))
      9                  )

~/anaconda3/lib/python3.7/site-packages/pandas/core/frame.py in applymap(self, func)
   6551             return lib.map_infer(x.astype(object).values, func)
   6552 
-> 6553         return self.apply(infer)
   6554 
   6555     # ----------------------------------------------------------------------

~/anaconda3/lib/python3.7/site-packages/pandas/core/frame.py in apply(self, func, axis, broadcast, raw, reduce, result_type, args, **kwds)
   6485                          args=args,
   6486                          kwds=kwds)
-> 6487         return op.get_result()
   6488 
   6489     def applymap(self, func):

~/anaconda3/lib/python3.7/site-packages/pandas/core/apply.py in get_result(self)
    149             return self.apply_raw()
    150 
--> 151         return self.apply_standard()
    152 
    153     def apply_empty_result(self):

~/anaconda3/lib/python3.7/site-packages/pandas/core/apply.py in apply_standard(self)
    255 
    256         # compute the result using the series generator
--> 257         self.apply_series_generator()
    258 
    259         # wrap results

~/anaconda3/lib/python3.7/site-packages/pandas/core/apply.py in apply_series_generator(self)
    284             try:
    285                 for i, v in enumerate(series_gen):
--> 286                     results[i] = self.f(v)
    287                     keys.append(v.name)
    288             except Exception as e:

~/anaconda3/lib/python3.7/site-packages/pandas/core/frame.py in infer(x)
   6549             if x.empty:
   6550                 return lib.map_infer(x, func)
-> 6551             return lib.map_infer(x.astype(object).values, func)
   6552 
   6553         return self.apply(infer)

pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()

<ipython-input-23-16b6be88d3a3> in <lambda>(title)
      5 missing_titles = (el_universal[missing_titles_mask]['url']
      6                       .str.extract(r'(?P<missing_titles>[^/]+)$')
----> 7                       .applymap(lambda title: title.split('-'))
      8                       .applymap(lambda title_word_list: ' '.join(title_word_list))
      9                  )

AttributeError: ("'float' object has no attribute 'split'", 'occurred at index missing_titles')```



Mi codigo es el siguiente:




missing_titles_mask = el_universal[‘title’].isna()

missing_titles = (el_universal[missing_titles_mask][‘url’]
.str.extract(r’(?P<missing_titles>[^/]+)$’)
.applymap(lambda title: title.split(’-’))
.applymap(lambda title_word_list: ’ '.join(title_word_list))
)
missing_titles```

Que puede estar mal en mi codigo ?

Saludos.

Alguien me podría explicar un poco mejor cómo funciona esta notación?
el_universal[missing_titles_mask][“url”]
Según entiendo, en la primera llave entran las filas no?
Dónde podría aprender un poco más sobre esta notación?

Aquí pueden encontrar más información sobre apply, applymap y map.

Tambíes se puede usar, “string”.replace("-"," ")

muy interesante!

Jajajaja cómo vas a empezar diciendo En un mundo ideal y yo acabando de verme aladdin con mi hermanito

Muy interesante estos ejercicios para la limpieza de los datos.

en mi codigo tuve que agregar rango de palabras a unir para que no cogiera el ‘.html’ que me salia al final de cada url

# 3. rellenar datos faltantes

missing_titles_mask = el_pais['title'].isna() #esto me da booleanos, devuelve True donde aparece NaN

missing_titles = (el_pais[missing_titles_mask]['url']
                    .str.extract(r'(?P<missing_titles>[^/]+)$')
                    .applymap(lambda title: title.split('-'))
                    .applymap(lambda title_word_list: ' '.join(title_word_list)[:-5]) # le pongo este rango[:-5] para que no coja el .html    
                  )

missing_titles

Hasta ahora no había entendido las funciones lambda, me sirvió también para aprender cómo funciona applymap!

aqui mi resultado…

aqui mi resultado…

Hace falta mucha práctica uff!

Excelente lo visto hasta ahora, todo el poder de pandas, pero tendre que adquirir bases fuertes, ire por ellas a los cursos de Platzi.

Algún experto en expresiones regulares que me ayude en esta parte, mi url es algo asi: (https://www.semana.com/opinion/articulo/despues-del-coronavirus-lo-siento-todo-puede-ser-peor-por-maria-jimena-duzan/662595 ) por lo que aplicarle el patrón que usa el profe solo me retorna (662595)

En los datos de mi Dataframe en los títulos vacíos no esta la expresión NaN, solo esta vacia como se aprecia en la imagen, como lo soluciono? ¿como modificar el código en el Jypyter para que en vez de buscar NaN busque el dato vacío?

Chale, Creí que NaN era: No ay Nada
pero según google es: Not a Number.
XD

HAY PAGINAS QUE DEVUELVEN UN ERROR CUANDO SE SCRAPEA LO QUE SE DEBE HACER ES COLOCARLE UN HEADER A LA PETICION GET PARA SIMULAR ESTAR ENTRANDO COMO UN NAVEGADOR

Para los que tengan error con .applymap o con replace

# 3. Rellenar datos faltantes
missing_titles_mask = el_universal['title'].isna()

missing_titles = (el_universal[missing_titles_mask]['url'].str.extract(r'(?P<missing_titles>[^/]+)$'))

missing_titles = ((missing_titles['missing_titles'].str.split('-')).str.join(' '))

missing_titles = missing_titles.to_frame()

missing_titles

Me toco buscar un periódico que tuviera más datos y además, que tuviera NaN, porque los ejemplos que había hecho, todos tenían título. Pero lo logré y finalmente pude comprender muy bien lo que se hizo.

Buen ejercicio. Seguimos ahora implementando en el código.

Hola! dejo mi solución para extraer los títulos faltantes, espero que les sirva. Un abrazo!

Con parsed_urls hago un split de las urls en base a ‘/’
parsed_urls=el_universal[missing_titles_mask][‘url’].map(lambda x: x.split(’/’))

#Esto me da una serie de listas. Sobre esto somo el ultimo elemento y y reemplazo ‘-’ por ’ ‘
new_titles=[((’ ‘.join(parsed_url[-1].split(’-’)))) for parsed_url in parsed_urls]
new_titles