No tienes acceso a esta clase

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

Preprocesamiento de datos: terminando de preparar y limpiar los datasets

27/28
Recursos

Aportes 43

Preguntas 7

Ordenar por:

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

Para hacer que los csv pasen a df en el código de David:

df_agri = pd.read_csv('API_AG.LND.AGRI.K2_DS2_en_csv_v2_716226.csv', header = 2)
df_fore = pd.read_csv('API_AG.LND.FRST.K2_DS2_en_csv_v2_716262.csv', header = 2)
df_elec = pd.read_csv('API_EG.USE.ELEC.KH.PC_DS2_en_csv_v2_715482.csv', header = 2)
df_co2e = pd.read_csv('API_EN.ATM.CO2E.KT_DS2_en_csv_v2_713263.csv', header = 2)
df_popu = pd.read_csv('API_SP.POP.TOTL_DS2_en_csv_v2_713131.csv', header = 2)

se me hizo un poco extraño la manera de generar la lista de años desde 1970 a 2015. dejo mi versión por si es de interés para alguien.

fechas = pd.date_range(start='1970', end='2015', freq='Y')
fechas =fechas.map(lambda x: str(x.year))
fechas

Para evitar hacer el merge tantas veces realicé la siguiente funcion:

def fun_merge(df1,df2):
    return pd.merge(df1,df2,on=['Country','name','date'], how = 'inner')

y luego simplemente la llamo

df_merge = fun_merge(df_merge,df_co2e)
df_merge = fun_merge(df_merge,df_elec)
df_merge = fun_merge(df_merge,df_agri)
df_merge = fun_merge(df_merge,df_fore)
df_merge

Una forma que me parece más sencilla de generar la lista de los años es con list comprehension:

years = [ str(i) for i in range(1971,2016)]
cols = ['Country Name','Country Code'] + years

Y algo que se le pasó al profesor es que la función range no es inclusiva al final, por lo que se deberia escribir range(1971,2016) para incluir el año 2015

Gente cuidado con la función dropna(), si ven bien al profesor ejecutarlo esta desapareciendo Afganistán porque no poseen datos de producción eléctrica (ni EEUU se atrevió a tanto). Siempre revisar la naturaleza de los NaN y premeditar las decisiones como científicos de datos

Buenas, para quienes toman los links y les aparece que no están disponibles, pueden entrar al Colab colocado como recurso de la clase y allí los links si funcionan correctamente, los dejo también aquí.

Temperature (°C) https://www.kaggle.com/berkeleyearth/climate-change-earth-surface-temperature-data#GlobalLandTemperaturesByCountry.csv

Topic https://data.worldbank.org/topic/climate-change

CO2 (kt) https://data.worldbank.org/indicator/EN.ATM.CO2E.KT

Forest (km2) https://data.worldbank.org/indicator/AG.LND.FRST.K2

Agricultura (km2) https://data.worldbank.org/indicator/AG.LND.AGRI.K2

Population (7mM) https://data.worldbank.org/indicator/SP.POP.TOTL

Electric power consumption (kWh per capita) https://data.worldbank.org/indicator/EG.USE.ELEC.KH.PC

En lugar de escribir una por una la conversión a tipo float, se puede hacer en la función que creamos para dar formato inicialmente.

def fun_format(df, col = 'agriculture'):
  df = df.loc[:, cols].melt(id_vars=['Country Name','Country Code']).rename(
    columns = {'variable':'year',
               'Country Name':'Country',
               'Country Code':'name',
               'value': col})
  df['year'] = df['year'].astype(float)
  return df

¿De verdad es recomendable en este caso hacer el drop? Pasamos de 7224 observaciones a 2735 :C

Normalmente creo interesante observar los NaN antes de solo hacer Drop, completarlos puede ser una buena opción, o simplemente concluir por qué no hay esos datos.

26-08-2020 cambiaron los nombres. aca van:


df_agri = pd.read_csv('API_AG.LND.AGRI.K2_DS2_en_csv_v2_1219309.csv', header = 2)
df_fore = pd.read_csv('API_AG.LND.FRST.K2_DS2_en_csv_v2_1221041.csv', header = 2)
df_elec = pd.read_csv('API_EG.USE.ELEC.KH.PC_DS2_en_csv_v2_1221097.csv', header = 2)
df_co2e = pd.read_csv('API_EN.ATM.CO2E.KT_DS2_en_csv_v2_1217566.csv', header = 2)
df_popu = pd.read_csv('API_SP.POP.TOTL_DS2_en_csv_v2_1308146.csv', header = 2)

pueden acceder a toda esa información de forma más rápida con

<code>
!pip install pandas-datareader

from pandas_datareader import wb

solo deben saber el código de los países y los indicadores

buena clase

Que buen ejercicio

Gran clase

Los datos de energía no están disponibles en el sitio (30/04/21), por favor compartir si alguien lo tiene.

Genial, muy importante esta clase!

Bien explicado y a ponerlo en práctica.

Una opción para obtener las columnas, considero es simplemente tomar un dataframe y tomar manualmente las columnas deseas, ejemplo:

df_popu.columns

Aquí me mostrará todas las columnas, señalo las de interés y luego:

cols =['Country Name', 'Country Code','1971', '1972', '1973', '1974', '1975', '1976', '1977',
       '1978', '1979', '1980', '1981', '1982', '1983', '1984', '1985', '1986',
       '1987', '1988', '1989', '1990', '1991', '1992', '1993', '1994', '1995',
       '1996', '1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004',
       '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013',
       '2014', '2015']
cols[:5]

Y ya está. Se hizo sin utilizar muchos comandos. Aun así me pregunto si será una buena práctica

agregandole a la función

df['year'] = df['year'].astype(float)

el primer perge se puede hacer simplemente así:

df_merge = pd.merge(df_tmed, df_popu)
df_merge

Para hacer el merge hice “simplemente”:

df_merge = pd.merge(df_tmed,df_popu)
df_merge = pd.merge(df_merge,df_co2e)
df_merge = pd.merge(df_merge,df_elec)
df_merge = pd.merge(df_merge,df_agri)
df_merge = pd.merge(df_merge,df_fore)
df_merge

Para la carga de los df, modificaciones y el merge utilice un ciclo for para evitar el copiar y pegar. Espero sea mas sencillo y una sintaxis mas limpia

import os   #Modulo para manipular las carpetas

data = [d for d in os.listdir('db/') if d[:4] == 'API_']
data_dict = {}
for d in data:
    data_dict[d[7:15]] = pd.read_csv('db/{}'.format(d), skiprows=4)

#Se guardaron los df en un diccionario

#Seleccionamos las columnas que queremos de cada df
for key, _ in data_dict.items():
    cols = ['Country Name', 'Country Code'] + list(map(str, range(1971,2015)))
    data_dict[key] = data_dict[key].loc[:,cols].melt(id_vars=['Country Name', 'Country Code'], var_name='date', value_name=data_dict[key].iloc[0,2])\
        .rename(columns={'Country Name':'Country', 'Country Code':'name'})

#Se convierte la columna date de cada DF a tipo int64
for key in data_dict.keys():
    data_dict[key]['date'] = data_dict[key]['date'].astype('int64')

#Se realiza el merge para tener un df compacto

df_merge = df_t_med[['Country', 'temperature','date']]
on_col = ['Country', 'date']
for df in data_dict.values():
    df_merge = pd.merge(df_merge, df, on=on_col, how='inner')
    on_col = ['Country', 'date', 'name']

#Se eliminan los na's
df_merge.dropna(inplace=True)

Espero sus comentarios!

He encontrado muy util en mi trabajo, me permite unir muchos datasets y hasta el momento no lo sabia haer de manera automatica

sinceramente dije NoOOoOooOoOoO le va a tocar cambiar todo a mano…

pues me callo la boca como solo un programador sabría hacerlo, que razón hay en la frase ~si es repetitivo es programable~

Un ciclo sencillo para no repetir el codigo:

for i in df_agri, df_fore, df_elec, df_co2e,df_popu:
  df_merge= pd.merge(df_merge,i,
                   on = ['Country','date','name'],
                   how='inner')

Recuerden eliminar del ciclo el dataframe que ya usaron, para que no se les repita alguna columna

Por cierto, tengan cuidado con el

df_merge.dropna()

En este caso como es de practica no tiene mucho problema, pero pasamos de 7224 filas de datos a 2750, casi que eliminamos el 62% de los datos.

Una manera automatica de hacer el cambio, sin tener que repetir codigo:

#creamos la funcion
def cambiar_tipo(df):
  df['date'] = df['date'].astype(float)
  return df

#Creamos una lista de los datasets
list_df= [df_agri, df_fore, df_elec, df_co2e,df_popu]

#Creamos un ciclo para que la funcion se corra en la lista creada
for i in list_df:
  cambiar_tipo(i)

Antes de escribir la función en Colab, los tres comandos anteriores los ejecuté en celdas aparte, cuando quise ejecutar la celda después de la función me arrojó error, demorpe hrs viendo que podría haber sido y es que los 3 comandos que van antes de la función no deben estar porque modifican el df_agri.
A los “errores” pero aqui vamos aprendiendo… :’)

Unir los DataFrmes con la funcion Merge

aunque no es muy bonito se puede hacer el merge en un solo paso:

df_merge = pd.merge(df_t_med,df_agri,on=[‘Country’,‘date’],how=‘inner’).merge(df_co2e,on=[‘Country’,‘date’,‘name’],how=‘inner’).merge(df_elec,on=[‘Country’,‘date’,‘name’],how=‘inner’).merge(df_fore,on=[‘Country’,‘date’,‘name’],how=‘inner’).merge(df_popu,on=[‘Country’,‘date’,‘name’],how=‘inner’)
df_merge

<h4>Para quién quiera hacer los merge con una función.</h4>
def merge_df(df1,df_list):
    df_merge = pd.merge(df1,df_list[0],how='inner',on=['Country','year','name'])
    for i in df_list[1:]:
        df_merge = pd.merge(df_merge,i,how='inner',on=['Country','year','name'])
    return df_merge
merge_df(df_merge,[df_co2,df_elc,df_pop,df_frst])

Pero claro que debimos haber limpiado también los data sets antes de hacer merge.
Recuerden:
Garbage in, garbage out

Bucle Merge:

Primer merge lo mantenemos para asi tener un formato definido y no se complique hacer el merge en bucle

df_merge = pd.merge(df_t_med[['Country', 'temperature', 'date']],
                    df_popu, on = ['Country', 'date'], how = 'inner')

Bucle FOR para merge

data_frame_list = [df_agri, df_co2e, df_elec, df_fore]

for i in data_frame_list:
    df_merge = pd.merge(df_merge,
                    i, on = ['Country', 'name', 'date'], how = 'inner')
    
df_merge

Les dejo el codigo del cambio de tipo de dato de “date”

df_popu['date']=df_popu['date'].astype(float)
df_fore['date']=df_fore['date'].astype(float)
df_agri['date']=df_agri['date'].astype(float)
df_elec['date']=df_elec['date'].astype(float)
df_co2e['date']=df_co2e['date'].astype(float)

muchachos al dia de hoy 30-03-2022 los links en la descripcion no sirven cojan los links del colab de profe aca les dejo el link

Para los que no quieren realizar muchas lineas de código, acá una forma de hacer merge en una sola linea (utilizando programación funcional).

from functools import reduce
dfs = [df_popu, df_fore, df_agri, df_elec, df_co2e]
df_merge = reduce(lambda left,right: pd.merge(left, right, on = ['Country', 'date'], how = 'inner'), dfs)

como me parecía engorroso repetir la lineá de código del merge realize esta función

def fun_merge(*dfs,base=df_t_med[['Country','temperature','date']]):
    merge_df = base
    merge_df = pd.merge(merge_df,dfs[0],on=['Country','date'], how = 'inner')#the firts needst to be without 'name'
    for df in dfs[1:] :
        merge_df = pd.merge(merge_df,df,on=['Country','name','date'], how = 'inner')
    return merge_df

así es como queda usándola

df_merge = fun_merge(df_popu,df_co2e,df_elec,df_agri,df_fore)

La verdad que me gustó mucho la clase. Creo que quedaría bastante mejor si se especificaran un poco que representan los números, ya que carecen de unidades.

Seria bueno que mostraras como estaban los dataset y porque en este caso usamos LOC en la base de agricultura

Con el uso de:

df_merge.dropna()

se eliminarán las filas que tengan al menos un elemento nulo.

Si se quiere saber cuantos elementos nulos hay por columna se emplea:

df_merge.isnull().sum()

Me corrigen si no es así pero, el header (header=2, para el ejercicio de la clase) se agrega a la filas en que hay texto antes de que se muestren los datos, es decir, si hay filas vacias antes de que se muestren los datos estas no son tenidas en cuenta en el dataset.

alguien mas ha tenido un problema con usar toda la memoria ram al realizar los merge del minuto 12:46? Cambie el entorno de ejecución, solicite mas memoria ram con
i = []
While True:
i.append(i)

pero nada de esto resulta, alguna recomendación?