analizzare un dataset con una sola riga di python

Maurizio Napolitano
4 min readNov 5, 2019

--

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 shell
pandas-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.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Maurizio Napolitano
Maurizio Napolitano

Written by Maurizio Napolitano

fbk, openstreetmap, gis, neocartography, okfn italy, open data, open source, software libero, sociologia, trento, pallavolo, digital commons lab

No responses yet

Write a response