initial repository creation
This commit is contained in:
commit
62d0803379
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
stazioni.csv
|
34
README
Normal file
34
README
Normal file
|
@ -0,0 +1,34 @@
|
|||
Software per il recupero delle informazioni dei dati dei sensori ambientali pubblicati dall'arpa sul portale opendata della regione lombardia
|
||||
|
||||
la lista delle stazioni e dai sensori si trova qui':
|
||||
https://www.dati.lombardia.it/Ambiente/Stazioni-qualit-dell-aria/ib47-atvt
|
||||
lo script stazioni.py stampa la lista delle stazioni e dei sensori recuperando i dati da link qui' sopra,
|
||||
se si salva invece il contenuto di quel link come stazioni.csv la ricerca viene fatta offline in questo file.
|
||||
|
||||
il portale contiene due tipi di documenti: i dataset e i files.
|
||||
i dataset esistono solo dal 2017 in avanti, sono annuali, e non contengono i dati dei sensori che ad oggi risultano non piu' attivi,
|
||||
(ad es. per un sensore che ha smesso di funzionare nel 2018 non sono piu' disponibili i dati del 2017).
|
||||
Sono interrogabili da remoto richiedendo solo i dati di sensori specifici, senza necessita' di scaricare tutto il dataset.
|
||||
|
||||
I files invece sono disponibilli in formato csv (non compressi o zippati), la lista attuale e' questa:
|
||||
sensori_aria_1968-1995.zip - 47M
|
||||
sensori_aria_1996-2000.zip - 67M
|
||||
sensori_aria_2001-2004.zip - 70M
|
||||
sensori_aria_2005-2007.zip - 62M
|
||||
sensori_aria_2008-2010.zip - 69M
|
||||
sensori_aria_2011.zip - 24M
|
||||
sensori_aria_2012.zip - 23M
|
||||
sensori_aria_2013.zip - 23M
|
||||
sensori_aria_2014.zip - 21M
|
||||
sensori_aria_2015.zip - 21M
|
||||
sensori_aria_2016.zip - 21M
|
||||
sensori_aria_2017.zip - 13M
|
||||
sensori_aria_2018.zip - 13M
|
||||
sensori_aria_2019.zip - 13M
|
||||
|
||||
per visualizzarne i dati e' necessario scaricare l'intero file e processarlo.
|
||||
|
||||
Quindi per l'analisi dei dati recenti e' piu' comodo lavorare con i dataset, per analisi storiche invece bisogna usare i csv
|
||||
|
||||
openlamb usa i dataset,
|
||||
in futuro ci sara' una versione che lavorera' con i csv
|
106
openlamb.py
Executable file
106
openlamb.py
Executable file
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/env python
|
||||
# pylint: skip-file
|
||||
|
||||
import argparse
|
||||
import traceback
|
||||
import sys
|
||||
import subprocess
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from sodapy import Socrata
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
datasets_ambiente = {"2020": "nicp-bhqi",
|
||||
"2019": "kujm-kavy",
|
||||
"2018": "bgqm-yq56",
|
||||
"2017": "j8j8-qsb2"}
|
||||
|
||||
|
||||
def _connect():
|
||||
client = Socrata("www.dati.lombardia.it", None)
|
||||
return client
|
||||
|
||||
def process_dataset(dataset, sensore):
|
||||
client = _connect()
|
||||
results = client.get(dataset, IdSensore=sensore)
|
||||
results_df = pd.DataFrame.from_records(results)
|
||||
try:
|
||||
results_df = results_df.astype({'valore': 'float64'})
|
||||
except:
|
||||
print('\nspiacente, dati non disponibili per il sensore %s') % sensore
|
||||
sys.exit(-1)
|
||||
results_df["data"] = pd.to_datetime(results_df["data"])
|
||||
results_df = results_df.replace(-9999, np.nan)
|
||||
results_df.sort_values(by=['data'], inplace=True)
|
||||
results_df.rename(columns = {'valore':sensore}, inplace = True)
|
||||
results_df.drop(columns=['idoperatore', 'idsensore', 'stato'], inplace = True)
|
||||
return results_df
|
||||
|
||||
|
||||
def merge_df(dataframes, sensori):
|
||||
df = dataframes[sensori[0]]
|
||||
for sensore in sensori[1:]:
|
||||
df = pd.merge(df, dataframes[sensore])
|
||||
return df
|
||||
|
||||
|
||||
def get_dataframes(datasets, sensori):
|
||||
dataframes = {}
|
||||
for sensore in sensori:
|
||||
df = process_dataset(datasets[0], sensore)
|
||||
for dataset in datasets[1:]:
|
||||
df = pd.concat([df, process_dataset(dataset, sensore)], axis=0)
|
||||
dataframes[sensore] = df
|
||||
return dataframes
|
||||
|
||||
|
||||
def plot_dataframe(dataframe):
|
||||
dataframe.plot(x='data')
|
||||
plt.axhline(y=50, color='black', linestyle='-', label='24-hour average EU limit')
|
||||
plt.show()
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--dataset", nargs='+', required=True, help="ricerca dei datasets")
|
||||
parser.add_argument('--sensori', nargs='+', required=True, help="specifica i sensori")
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
datasets = []
|
||||
if "all" in args.dataset:
|
||||
for k in datasets_ambiente.keys():
|
||||
datasets.append(datasets_ambiente[k])
|
||||
else:
|
||||
for d in args.dataset:
|
||||
datasets.append(datasets_ambiente[d])
|
||||
sensori = args.sensori
|
||||
dataframes = get_dataframes(datasets, sensori)
|
||||
datamerged = merge_df(dataframes, sensori)
|
||||
import stazioni
|
||||
s = stazioni.get_stazioni()
|
||||
for sensore in sensori:
|
||||
location = s.loc[s['idsensore'] == sensore, 'nomestazione'].iloc[0]
|
||||
print('Valore medio per il sensore %s %s: %s' % (sensore, location, datamerged[sensore].mean().round(1)))
|
||||
plot_dataframe(datamerged)
|
||||
|
||||
|
||||
except KeyError:
|
||||
print("\nErrore:")
|
||||
#print("Datasets disponibili:")
|
||||
#print('\n'.join([str(lst) for lst in sorted(datasets_ambiente.keys())]))
|
||||
traceback.print_exc()
|
||||
except KeyboardInterrupt:
|
||||
print("program terminated by user")
|
||||
except SystemExit:
|
||||
print("program terminated, bye")
|
||||
except:
|
||||
print("\nAn unhandled exception occured, here's the traceback!\n")
|
||||
traceback.print_exc()
|
||||
print("\nReport this to putro@autistici.org")
|
||||
sys.exit()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
40
stazioni.py
Executable file
40
stazioni.py
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env python
|
||||
# pylint: skip-file
|
||||
|
||||
import os.path
|
||||
import pandas as pd
|
||||
from sodapy import Socrata
|
||||
|
||||
|
||||
def _connect():
|
||||
client = Socrata("www.dati.lombardia.it", None)
|
||||
return client
|
||||
|
||||
|
||||
def get_stazioni(offline=False):
|
||||
if offline:
|
||||
stazioni = pd.read_csv("stazioni.csv")
|
||||
stazioni_df = pd.DataFrame.from_records(stazioni)
|
||||
stazioni_df.drop(columns=["Storico", "Idstazione", "Utm_Nord", "UTM_Est", "lat", "lng", "location", "Limiti amministrativi 2014 delle province di Regione Lombardia", "Limiti amministrativi 2015 delle province di Regione Lombardia"], inplace=True)
|
||||
stazioni_df.columns = [x.lower() for x in stazioni_df.columns]
|
||||
else:
|
||||
client = _connect()
|
||||
stazioni = client.get("ib47-atvt")
|
||||
stazioni_df = pd.DataFrame.from_records(stazioni)
|
||||
stazioni_df.drop(columns=[":@computed_region_6hky_swhk", ":@computed_region_ttgh_9sm5", "utm_est", "utm_nord", "storico", "idstazione", "lat", "lng", "location"], inplace=True)
|
||||
stazioni_df["datastart"] = pd.to_datetime(stazioni_df["datastart"])
|
||||
stazioni_df["datastop"] = pd.to_datetime(stazioni_df["datastop"])
|
||||
return stazioni_df
|
||||
|
||||
|
||||
def print_stazioni():
|
||||
pd.set_option('display.max_rows', None)
|
||||
if os.path.exists("stazioni.csv"):
|
||||
stazioni = get_stazioni(offline=True)
|
||||
else:
|
||||
stazioni = get_stazioni()
|
||||
print(stazioni)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print_stazioni()
|
Loading…
Reference in New Issue
Block a user