In questo articolo descriviamo le principali istruzioni per l’analisi dei dati della libreria Pandas di Python e le confrontiamo con la sintassi SQL equivalente. I metodi di Python saranno applicati ai Dataframe, una struttura dati molto simile alle tabelle dei Database relazionali, che organizza i dati in colonne tipizzate e righe ordinate.
Import di pandas e operazioni preliminari
Per prima cosa occorre importare la libreria pandas tramite l’istruzione
import pandas as pd
A questo punto possiamo creare un DataFrame a partire dai dati dal file Clienti.csv salvato sul mio repository di Github. Non c’è bisogno che lo scarichi, pandas è in grado di acquisire anche file csv salvati sul web!
clienti = pd.read_csv(filepath_or_buffer = \ "https://raw.githubusercontent.com/iantomasinicola/Esercizi/main/Clienti.csv", sep = ";", header = 0, usecols = ["NumeroCliente","Nome","Cognome", "DataNascita","Regione"], parse_dates = ["DataNascita"])
Selezionare i dati di un DataFrame con Pandas
Per visualizzare il contenuto delle colonne Nome e Cognome del DataFrame clienti scriveremo
clienti[["Nome", "Cognome"]]
equivalente alla query SQL
SELECT Nome, Cognome FROM Clienti;
Per evitare la visualizzazione di un numero eccessivo di dati, le istruzioni della libreria Pandas mostrano di default soltanto alcune delle colonne e delle righe selezionate. Per modificare questo comportamento possiamo lanciare le istruzioni
pd.set_option('display.max_columns', None) pd.set_option('display.max_rows', None)
Se vogliamo visualizzare tutte le colonne basterà eseguire la riga di codice contenente soltanto il nome del DataFrame.
Filtrare i dati di un DataFrame con Pandas
Vediamo il codice per estrarre tutte le informazioni dei clienti della regione Lazio:
clienti[clienti["Regione"] == "Lazio"]
che è equivalente al codice SQL
SELECT * FROM Clienti WHERE Regione = 'Lazio';
Vediamo ora come scrivere filtri più complessi, ad esempio per estrarre il NumeroCliente e il Nome dei clienti della regione Lazio che si chiamano Giovanni:
clienti[(clienti["Regione"] == "Lazio") \ & (clienti["Nome"] == "Giovanni")] \ [["NumeroCliente", "Nome"]]
Il carattere \ serve semplicemente per andare a capo nella scrittura del codice Python. L’istruzione precedente è equivalente alla query SQL
SELECT NumeroCliente, Nome FROM Clienti WHERE Regione='Lazio' AND Nome='Giovanni';
Il carattere corrispondente nella sintassi di Pandas all’operatore OR è la barra verticale “|“. Ricordiamoci sempre di racchiudere le condizioni tra parentesi tonde.
Vediamo infine come scrivere un filtro equivalente all’IN di SQL:
clienti[clienti["Regione"].isin(["Piemonte","Lazio"])] \ [["NumeroCliente", "Nome", "Regione"]]
è equivalente a
SELECT NumeroCliente, Nome, Regione FROM Clienti WHERE Regione IN ('Piemonte', 'Lazio');
ed estrae i valori delle colonne NumeroCliente, Nome e Regione dei clienti residenti in Piemonte e Lazio.
Anche su pandas dobbiamo fare particolare attenzione ai null:
clienti[(clienti["Regione"].isna())] clienti[(clienti["Regione"].notna())]
sono equivalenti ai filtri SQL regione IS NULL e regione IS NOT NULL. Ricordiamo infine questa importante differenza tra i due linguaggi nel caso in cui scriviamo un filtro con l’operatore != (diverso da). L’istruzione
clienti[(clienti["Regione"] != "Lazio"]
riporterà anche le righe dove la Regione è null, ciò non accade invece con il codice SQL
SELECT * FROM Clienti WHERE Regione <> 'Lazio';
Puoi ripassare e approfondire questi concetti con la prossima video-lezione
Metodo group by e agg per aggregare i dati di un DataFrame
Vediamo ora l’equivalente della clausola Group By su pandas. Per prima cosa importiamo un nuovo file
fatture = pd.read_csv(filepath_or_buffer = \ "https://raw.githubusercontent.com/iantomasinicola/Esercizi/main/Fatture.csv", sep = ";", header = None, names = ["NumeroFattura","Tipologia","Importo", "Iva","IdCliente","ResidenzaCliente", "DataFattura","NumeroFornitore"], parse_dates = ["DataFattura"], decimal = ",", )
Vediamo una sintassi che richiede almeno la versione 1.1.5 di Pandas. Per calcolare il numero di Fatture per ogni fornitore importiamo la libreria numpy e usiamo i metodi .groupby e .agg
import numpy as np fatture.groupby(by = "NumeroFornitore", as_index = False, dropna = False) \ .agg(conteggio = ("NumeroFattura", np.size) )
equivalente al codice SQL
SELECT NumeroFornitore, COUNT(*) FROM Fatture GROUP BY NumeroFornitore;
Se dobbiamo scrivere un’aggregazione su più colonne, ad esempio su NumeroFornitore e IdCliente, che calcoli anche somme e medie, useremo:
- una lista nel parametro by di groupby
- i metodi sum, mean e size di numpy nell’agg.
fatture.groupby(by = ["NumeroFornitore", "IdCliente"], as_index = False, dropna = False) \ .agg( somma_importo = ("Importo", np.sum), media_importo = ("Importo", np.mean), conteggio = ("NumeroFattura", np.size))
L’argomento dropna=False è necessario per evitare che vengano eliminate le righe contenenti dei null nelle colonne raggruppate. Puoi trovare un mio approfondimento sul metodo groupby in questo articolo.
Metodo merge per combinare i dati di più DataFrame
Siamo arrivati finalmente alla classica operazioni di join, che su pandas corrisponde al metodo merge. Ad esempio una inner join tra le tabelle Fatture e Clienti come questa
SELECT * FROM Fatture AS F INNER JOIN Clienti AS C ON F.IdCliente = C.NumeroCliente;
è equivalente a una merge tra DataFrame scritta in questo modo
pd.merge(fatture, clienti, how = "inner", left_on = "IdCliente", right_on = "NumeroCliente")
Se i due DataFrame hanno delle colonne con lo stesso nome, saranno disambiguate nell’output finale dai suffissi “_x” e “_y”. Tali suffissi sono customizzabili tramite il parametro suffixes, scrivendo ad esempio suffixes = (“_fatture”, “_clienti”). Le varie tipologie di join SQL sono eseguibili su pandas valorizzando correttamente l’argomento how. I termini inner, left, right e cross coincidono, invece la full join va tradotta con il valore outer. In questo articolo trovi un approfondimento sul metodo merge di Pandas.
Link utili
- Esercizi Python sui Dataframe con cui fare pratica https://www.yimp.it/esercizi-python-con-soluzioni-pandas-e-analisi-dei-dati/
- Come creare un grafico 3D con python https://www.yimp.it/grafico-3d-python/
- Il mio video corso su Python e il Machine Learning https://www.yimp.it/python-pandas-e-machine-learning/