analizzare un dataset con una sola riga di python
In questi giorni mi hanno girato una discreta quantità di dataset in formato shapefile (quindi geografici) da analizzare.
Come i tutti questi casi accade che molti dati sono incompleti, le variabili categoriali diverse e con tanti sinonimi, valori anomali nella distribuzione (d’altronde, se qualcuno inserisce le lunghezze in metri ed altri in centimetri nello stesso campo, cosa può accadere?) e molto altro ancora.
Da buon “spippolatore” ho cominciato a guardare i dati uno alla volta, aprendoli con QGIS.
Dovendo però guardare anche le tabelle degli attributi il tutto mi ha convinto ad utilizzare python con la classica configurazione da data scientist: (geo)pandas in jupyter notebook.
Da qui tutta una serie di istruzioni
# import dei moduli necessari
import geopandas as gpd
import numpy as np # caricamento dello shapefile del Comune di Trento con gli incidenti in un geodataframe (geopandas)
incidenti = gpd.read_file("http://webapps.comune.trento.it/cartografia/gis/dbexport?db=base&sc=vigili&ly=incidenti&fr=shp")# informazioni sulle colonne
incidenti.info() # descrizione delle colonne
incidenti.describe() # descrizione delle colonne testuali incidenti.describe(include=np.object)
con il fine di conoscere come è strutturato il dataset degli incidenti georeferenziati del Comune di Trento rilasciati in open data per arrivare ad una prima conclusione di avere una statistica del numero di incidenti per anno.
incidenti['anno'] = incidenti['anno'].fillna(0).astype({"anno":'int64'}) incidenti.groupby('anno').size().plot.bar(figsize=(15,15))

e da qui poi proseguire creando mappe di intensità
from colorcet import fire
import datashader as ds
from datashader import transfer_functions as tf agg = ds.Canvas().points(incidenti, 'x_gps', 'y_gps')
tf.set_background(tf.shade(agg, cmap=fire),"black")

o interattive
import folium
x = incidenti.to_crs({"init": "epsg:4326"}).unary_union.envelope.centroid.x
y = incidenti.to_crs({"init": "epsg:4326"}).unary_union.envelope.centroid.y m = folium.Map([y,x], zoom_start=11, tiles="stamenterrain") for index, row in incidenti.to_crs({"init": "epsg:4326"}).iterrows():
folium.CircleMarker(
location=[row.geometry.y,row.geometry.x],
radius=1,
color='red',
fill=True,
fill_color='orange' ).add_to(m)folium.LayerControl(collapsed=False).add_to(m) m

L’analisi per investigare i dati può portare così a continuare attraverso la chiamata di varie funzioni di pandas e geopandas.
Pandas Profiling
Il problema è però comune a chiunque voglia investigare i dati e, se il metodo .describe() già dice qualcosa di utile, sicuramente qualcuno ha già pensato ad insieme di funzioni da mettere in batteria per produrre un report.
E così, con oggi, ho scoperto pandas-profiling
Il suo uso è immediato:
una volta installato il pacchetto
pip install pandas_profiling
è sufficiente aggiungere il metodo .profile_report() ad un dataframe e magicamente compare un intera pagina HTML con un report molto completo!!!
nel mio caso sono davanti ad un geodataframe prodotto da geopandas e, pertanto lo devo “declassare” a dataframe usando pandas e rinunciando alla colonna delle geometrie
import pandas as pd
import pandas_profiling df = pd.DataFrame(incidenti.drop(columns='geometry')) df.profile_report(title='Incidenti a Trento',style={'full_width':True})
Si può anche decidere di salvare l’output su un file .html
qui il risultato
profile = df.profile_report(title='Report dataset incidenti Trento')
profile.to_file(output_file="output.html")
e nota ancora più meravigliosa è stato prodotto anche il comando per shellpandas-profiling
Nota per gli utenti Colab Google
qualora ne fate uso da Colab di Google il comando di installazione del modulo deve essere fatto con questa sintassi:
!pip install -U pandas-profiling
Ok! Ma con una riga di python?
Vediamo ora di mettere in pratica il tutto con “una” riga di python in ambiente jupyter notebook che preveda già l’installazione dei pacchetti pandas e pandas_profiling.
L”esempio di partenza è quello del csv con le Farmacie della Provincia Autonoma di Trento.
Il cui file si recupera a questo indirizzo http://servizi.apss.tn.it/opendata/FARM001.csv
In python basta seguire queste istruzioni
import pandas
import pandas_profiling
pd.read_csv("http://servizi.apss.tn.it/opendata/FARM001.csv").profile_report()
l’istruzione
pd.read_csv(“http://servizi.apss.tn.it/opendata/FARM001.csv").profile_report()
è quella che produce l’intero report
nota:
guardando attentamente il report prodotto si scopre un errore nei dati:
le farmacie sono 175 e, per ciascuna, sono associati i valori di latitudine e longitudine.
Ci si aspetterebbe di avere 175 valori univoci per ciascun valore di latitudine e longitudine, invece sono 158.
Pertanto è molto probabile che ci siano diverse farmacie le cui coordinate risultano uguali.
Originally published at http://de.straba.us on November 5, 2019.