#!/usr/bin/env python # coding: utf-8 # # Python e Pandas - Nozioni e operazioni base # # **questo notebook è utile come riferimento *-cassetta degli attrezzi-* per le attività formative del DataLifeLab e per le esercitazioni in classe del corso di Open Notebook Science del dell'Università di Firenze** # # ## Python - nozioni base # # * Assegnazione variabili, stampa e indentificazione tipo di dati della variabile # * tipi di dati # * Numeri e operatori # * Stringhe # * Liste # * Dictionari # * Valori Booleani # * Tuple # * Set # * Operatori di comparazione # * Condizioni (if, elif, else, try-except) # * Cicli For # * Cicli While # * range() # * list comprehension # * funzioni # * expressioni lambda # * metodi # # ## Python - operazioni su file # # * aprire un file in lettura # * aprire un file in scrittura # # ## Pandas - nozioni base # # * Importare correttamente la libreria # * Crare un DataFrame # * DataFrame e Serie # * Filtrare DataFrame e Serie # * Concatenazione e Merge # * Tabella Pivot # * Formato Wide e Long (melt) # * Applicare una funzione alle celle # * Aprire e creare un file # * excel # # ## Pandas - funzioni statistiche di base # # * Describe # * media # * deviazione standard # * correlazione # # ## Pandas - grafici di base # # # Python # ## Assegnazione variabili, stampa e indentificazione tipo di dati della variabile # In[112]: variabile = "qualsiasi cosa in python è un oggetto" # In[113]: variabile # In[114]: print(variabile) # In[115]: type(variabile) # ## tipi di dati # # ### Numeri # In[116]: # interi 1 # In[117]: # numeri con virgola (float) 1.4 # In[118]: # operazioni 1 + 1 # In[119]: 1 * 3 # In[120]: 1 / 2 # In[121]: 2 ** 4 # In[122]: # modulo o resto 4 % 2 # In[123]: 5 % 2 # In[124]: (2 + 3) * (5 + 5) # ## Stringhe # In[125]: 'testo compreso fra apostrofi' # In[126]: "virgolette" # In[127]: " testo che contiene apostrofi ' " # ## Liste # In[128]: [1,2,3] # In[129]: ['ciao',1,[1,2]] # In[130]: la_mia_lista = ['a','b','c'] # In[131]: la_mia_lista.append('d') # In[132]: la_mia_lista # In[133]: la_mia_lista[0] # In[134]: la_mia_lista[1] # In[135]: la_mia_lista[1:] # In[136]: la_mia_lista[:1] # In[137]: la_mia_lista[0] = "modifico l'elemento zero" # In[138]: la_mia_lista # In[139]: lista_nested = [1,2,3,[4,5,['secondo livello del terzo elemento']]] # In[140]: lista_nested # In[141]: lista_nested[3] # In[142]: lista_nested[3][2] # ## Dizionari # In[143]: d = {'chiave1':'elemento1','chiave2':'elemento2'} # In[144]: d # In[145]: d['chiave1'] # In[146]: d.keys() # ## Valori Booleani # In[147]: True # In[148]: False # In[149]: ## Turple # In[150]: t = (1,2,3) # In[151]: t[0] # In[152]: # t[0] = 'NEW' # TypeError: 'tuple' object does not support item assignment # In[153]: ## Sets # In[154]: {1,2,3} # In[155]: {1,2,3,1,2,1,2,3,3,3,3,2,2,2,1,1,2} # ## Operatori di comparazione # In[156]: 1 > 2 # In[157]: 1 < 2 # In[158]: 1 >= 1 # In[159]: 1 <= 4 # In[160]: 1 == 1 # In[161]: 'hi' == 'bye' # ## Operatori Logici # In[162]: (1 > 2) and (2 < 3) # In[163]: (1 > 2) or (2 < 3) # In[164]: (1 == 2) or (2 == 3) or (4 == 4) # In[165]: #Gestione eccezioni # In[166]: if 1 < 2: print('bene!') # In[167]: if 1 < 2: print('bene') else: print('altrimenti') # In[168]: if 1 > 2: print('bene') else: print('altrimenti') # In[169]: if 1 == 2: print('primo') elif 3 == 3: print('intermedio') else: print('ultimo') # In[170]: try: print("10") except: print("fai qualcosa in caso di errore") # In[171]: #print(int("mamma")) #ValueError: invalid literal for int() with base 10: 'mamma' # In[172]: try: print(int("mamma")) except: print("fai qualcosa in caso di errore") # ## Cicli Loop # In[173]: seq = [1,2,3,4,5] # In[174]: for item in seq: print(item) # In[175]: for item in seq: print('Bene!') # In[176]: for nome_a_caso in seq: print(nome_a_caso+nome_a_caso) # In[177]: ## Ciclo while # In[178]: i = 1 while i < 10: print('i is: {}'.format(i)) i = i+1 # In[179]: ## range() # In[180]: range(10) # In[181]: for i in range(5): print(i) # In[182]: list(range(5)) # ## Metodi # In[183]: st = 'Marco saluta il Mondo' # In[184]: # lista di metodi e attributi dir(st) # In[185]: st.lower() # In[186]: st.upper() # In[187]: st.split() # In[188]: post = 'si parla di scienza! #DataLifeLab' # In[189]: post.split('#') # In[190]: post.split('#')[1] # In[191]: d # In[192]: d.keys() # In[193]: d.items() # In[194]: 'x' in [1,2,3] # In[195]: 'x' in ['x','y','z'] # # Operazioni su file # In[196]: # aprire un file di testo in sola lettura # il file si trova nella cartella Esercizio_1 all'interno della cartella esercizi e il nome del file è albert.txt with open("./esercizi/Esercizio_1/albert.txt" , "r") as miofile: contenuto_mio_file = miofile.read() print(contenuto_mio_file) # In[197]: # aprire un file di testo in scrittura # il file si trova nella cartella Esercizio_2 all'interno della cartella esercizi e il nome del file è Luigino.txt contenuto = ''' Luigino è stato uno dei più grandi artisti lirici della storia di San Marino Nascita: 14 marzo 1945, San Marino, San Marino. Decesso: 18 aprile 2015, San Marino, San Marino. Altezza: 1,75 m Peso: 205 KG ''' with open("./esercizi/Esercizio_2/Luigino.txt", "w") as miofile: contenuto_mio_file = miofile.write(contenuto) # ## Funzioni # In[198]: def mia_funzione(parametro='default'): """ documentazione della funzione va qui. """ return(parametro) # In[199]: mia_funzione # In[200]: mia_funzione() # In[201]: mia_funzione("marco") # In[202]: def area_triangolo(base, altezza): return base * altezza / 2 # In[203]: area_triangolo(10,15) # In[204]: ## Espressioni Lambda # In[205]: def la_variabile_per_2(var): return var*2 # In[206]: la_variabile_per_2(10) # In[207]: a = lambda var: var*2 # In[208]: a(10) # # Pandas - nozioni base # In[209]: import numpy as np import pandas as pd #costruzione di un dataframe df = pd.DataFrame({'col1':[1,2,3,4],'col2':[444,800,1200,444],'col3':['abc','abc','ghi','xyz']}) df # !["DataFrame"](https://www.kdnuggets.com/wp-content/uploads/pandas-02.png "DataFrame") # In[210]: ## filtrare i dati con **loc** # In[211]: # filtrare passando i valori di indice e colonna df.loc[3,"col3"] # In[212]: df.loc[2,["col2", "col3"]] # In[213]: df.loc[[2,1],["col2", "col3"]] # In[214]: (df['col2']==444) # filtrare passando un vettore boleano # In[215]: df.loc[(df['col1']>3) & (df['col2']==444), :] # In[216]: #oppure filtro1 = df['col1']>2 filtro2 = df['col2']==444 df.loc[filtro1 & filtro2, :] # In[217]: df.loc[(df['col1']>2) | (df['col2']==444), :] # In[218]: # assegnazione di valori # In[219]: #assegnazione ad un intera riga df.loc[(df['col1']>2) & (df['col2']==444), :] = 10 df # In[220]: #filtro tramite isin #si passa una lista di valori su cui effettuare il filtro df[df["col3"].isin(["ghi", "abc"])] # In[221]: #certe volte può essere utile filtrare "stile battaglia navale", passando per il numero di riga e di colonna # questo si può fare con iloc df.iloc[0:1,1:3] #prendo la seconda e terza colonna e la prima riga (indipendentemente dal valore del'indice) # In[222]: ## Operazioni fra colonne e righe # creazione di una nuova colonna nuova_colonna = df["col1"] + df["col2"] # In[223]: df["nuova_colonna"] = nuova_colonna df # In[224]: #sommare interi con stringa porta ad errore #df["col1"] + df["col3"] #TypeError: unsupported operand type(s) for +: 'int' and 'str' # In[225]: df[["col1", "col2", "nuova_colonna"]].div(df["nuova_colonna"], axis = 0) * 100 # In[226]: #per approfondire https://pandas.pydata.org/pandas-docs/stable/api.html#id4 # In[227]: altezze = pd.DataFrame({'Nome':["Marco","Luigi","Nino","Ugo", "Marino" ],'Altezza':[175,173,178,182,160]}) pesi = pd.DataFrame({'Nome':["Marco","Luigi","Vittorio","Ugo", "Marino" ],'Peso':[75,70,100,97,50]}) # In[228]: #concatenazione verticale # https://pandas.pydata.org/pandas-docs/stable/generated/pandas.concat.html pd.concat([altezze, pesi]) # In[229]: #concatenazione orizzonate pd.concat([altezze, pesi], axis = 1) ## i dati sono disallineati # In[230]: # join dei dati # https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.merge.html pd.merge(altezze, pesi, how = "outer", left_on = "Nome", right_on = "Nome") # In[231]: # aggiunto Gabriele e la sua altezza altezze = altezze.append([{"Nome": "Gabriele", "Altezza": 213}], ) # In[232]: pd.merge(altezze, pesi, how = "right", left_on = "Nome", right_on = "Nome") # In[233]: pd.merge(altezze, pesi, how = "left", left_on = "Nome", right_on = "Nome") # In[ ]: # In[234]: # da formato wide a long # https://pandas.pydata.org/pandas-docs/stable/generated/pandas.melt.html wide = pd.merge(altezze, pesi, how = "left", left_on = "Nome", right_on = "Nome") # In[235]: #calcolo un indice di massa corporea wide["Imc"] = wide["Peso"] / (wide["Altezza"] / 100) ** 2 # In[236]: wide # In[237]: long = pd.melt(wide, id_vars = "Nome", value_vars=['Altezza', 'Peso', "Imc"], var_name='Variabile', value_name= "Valori") # In[238]: long # In[239]: # tabella pivot # https://pandas.pydata.org/pandas-docs/stable/generated/pandas.pivot_table.html pd.pivot_table(long, values = "Valori", index = "Variabile", aggfunc = np.mean) # In[240]: #operazioni di riga e di cella wide.loc[:, ["Altezza", "Peso"]].apply(np.mean, axis = 0) # asse 0, vuol dire esegue l'operazione per colonna, asse 1 vuol dire per riga # In[241]: # operazione lambda def recode_altezza(altezza): if altezza >= 185: return "Alto" elif altezza < 185 and altezza > 165: return "Medio" else: return "Basso" wide["Altezza"].apply(recode_altezza) # In[242]: wide.loc[:, ["Altezza", "Peso"]].applymap(lambda cella: str(cella) + "_ciao") # In[243]: #Da long a wide long.pivot(index='Nome', columns='Variabile', values='Valori') # In[ ]: # # Creare o aprire file excel # In[244]: #Creare un file excel long.to_excel("excel_di_exempio.xlsx") # In[245]: #Leggere un file excel pd.read_excel("excel_di_exempio.xlsx") # In[246]: # Creare un file excel con più tab writer = pd.ExcelWriter('excel_di_esempio2.xlsx') long.loc[long["Variabile"] == "Altezza"].to_excel(writer,'Altezza') long.loc[long["Variabile"] == "Peso"].to_excel(writer,'Peso') long.loc[long["Variabile"] == "Imc"].to_excel(writer,'Imc') writer.save() # In[247]: # Leggere un file excel con più tab tab_multiple = pd.read_excel('excel_di_esempio2.xlsx', sheetname = None) tab_multiple # In[248]: # accedere ad una tab tab_multiple["Altezza"] # ## Pandas - funzioni statistiche # In[249]: wide.describe() # In[250]: # media wide["Altezza"].mean() # In[251]: # deviazione standard # indice di dispersione wide["Altezza"].std() # In[252]: # correlazione wide.corr() # ![](https://www.kdnuggets.com/wp-content/uploads/pandas-08.png "alcune stats") # In[253]: # iterazione con lambda per eseguire operazioni complesse fra colonne wide.apply(lambda x: (x['Altezza'] / x["Peso"]) , axis=1) # In[254]: # iterazione classica sui dati di un dataframe di pandas #Può essere molto utile quando si deve eseguire calcoli che è difficile rappresentare in lambda e si vuole adoperare (difetto principale: richiede maggiore tempo di esecuzione) for i, v in wide.items(): # qui prendo indice e valori print(i, v) # In[255]: # iterazione classica sui dati di una serie di pandas for i, v in wide["Altezza"].items(): # qui prendo indice e valori print(i, v) # ## Pandas - grafici di base # In[256]: serie_dati = {"Italia": {2010: 35, 2011: 30, 2012: 25}, "Spagna": {2010: 25, 2011: 27, 2012: 34}} # In[257]: df_serie_dati = pd.DataFrame(serie_dati) # In[258]: df_serie_dati # In[259]: get_ipython().run_line_magic('matplotlib', 'inline') import matplotlib import matplotlib.pyplot as plt # In[260]: df_serie_dati.plot(kind = "line", grid = True, rot=45, figsize = (10,5)) # In[261]: df_serie_dati.index = pd.to_datetime(df_serie_dati.index, format="%Y") # In[262]: df_serie_dati # In[263]: df_serie_dati.plot(kind = "line", grid = True, rot=45, figsize = (10,5)) # In[264]: Altezza = tab_multiple["Altezza"] # In[265]: Altezza # In[266]: Altezza.plot(y= "Valori", kind = "box", grid = True, rot=45, figsize = (10,5)) # In[267]: Altezza.plot(x="Nome", y= "Valori", kind = "bar", grid = True, rot=45, figsize = (10,5)) # In[268]: ax = Altezza.plot(x="Nome", y= "Valori", kind = "bar", grid = True, rot=45, figsize = (10,5)) ax.set_ylabel('Infant mort. rate') ax.set_xlabel('Country') for riga in range(Altezza.shape[0]): ax.annotate(Altezza["Valori"][riga], (Altezza.index[riga], Altezza["Valori"][riga]), xytext=(15, 15), textcoords='offset points', arrowprops=dict(arrowstyle='-|>')) plt.show() # In[ ]: