openlamb/openlamb.py

158 lines
5.3 KiB
Python
Executable File

#!/usr/bin/env python
import argparse
import traceback
import sys
import pandas as pd
import numpy as np
from sodapy import Socrata
import matplotlib.pyplot as plt
import glob
import os
from os import getcwd, chdir
path_to_csv_files = "csv/"
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 read_data_online(dataset, sensore):
client = _connect()
return client.get(dataset, IdSensore=sensore)
def read_data_from_csv(datafile):
return pd.read_csv("csv/" + datafile, usecols=['IdSensore', 'Data', 'Valore', 'Stato', 'idOperatore'])
def process(dati, sensore, csv):
""" processa i dati per un sensore da un dataset o un file csv e restituisce un dataframe """
print('Sto processando i dati del sensore %s per l\'origine dati %s...' % (sensore, dati))
if csv:
results = read_data_from_csv(dati)
else:
results = read_data_online(dati, sensore)
results_df = pd.DataFrame.from_records(results)
results_df.columns = [x.lower() for x in results_df.columns]
try:
results_df = results_df.astype({'idsensore': 'int64'})
results_df = results_df[results_df['idsensore'] == int(sensore)]
results_df = results_df.astype({'valore': 'float64'})
results_df["data"] = pd.to_datetime(results_df["data"])
results_df = results_df.replace(-9999, np.nan)
except:
print('\nERRORE: dati non disponibili per il sensore %s\n') % sensore
traceback.print_exc()
sys.exit(-1)
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):
""" fonde diversi dataframes in un dataframe unico con un sensore per colonna """
df = dataframes[sensori[0]]
for sensore in sensori[1:]:
df = pd.merge(df, dataframes[sensore])
return df
def get_dataframes(dati_csv, dati, sensori):
""" salva in un dict i dataframes dei vari sensori richiesti """
dataframes = {}
for sensore in sensori:
if dati_csv:
df = process(dati_csv[0], sensore, True)
for d in dati_csv[1:]:
df = pd.concat([df, process(d, sensore, True)], axis=0)
df.rename(columns={sensore: sensore + "-csv"}, inplace=True)
dataframes[sensore + "-csv"] = df
if dati:
df = process(dati[0], sensore, False)
for d in dati[1:]:
df = pd.concat([df, process(d, sensore, False)], axis=0)
dataframes[sensore] = df
return dataframes
def plot_dataframe(dataframe):
dataframe.plot(x='data')
plt.axhline(y=50, color='black', linestyle='-', label='EU limit')
plt.show()
def list_of_csv_files(dir_name):
saved = getcwd()
os.chdir(dir_name)
filelist = glob.glob('*.zip')
chdir(saved)
return filelist
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--dataset", nargs='+', required=False,
help="ricerca dei datasets")
parser.add_argument("--csv", nargs='+', required=False,
help="ricerca nei files csv")
parser.add_argument('--sensori', nargs='+', required=True,
help="cerca i dati di questi sensori")
args = parser.parse_args()
try:
dati_csv = []
csv_files = list_of_csv_files(path_to_csv_files)
if args.csv:
if "all" in args.csv:
dati_csv = csv_files
else:
for d in args.csv:
if d in csv_files:
dati_csv.append(d)
else:
print("spiacente, ma il file csv %s non e' disponibile nel "
"percorso indicato: %s" % (d, path_to_csv_files))
sys.exit(-1)
dati = []
if args.dataset:
if "all" in args.dataset:
for k in datasets_ambiente.keys():
dati.append(datasets_ambiente[k])
else:
for d in args.dataset:
dati.append(datasets_ambiente[d])
dataframes = get_dataframes(dati_csv, dati, args.sensori)
datamerged = merge_df(dataframes, dataframes.keys())
import stazioni
s = stazioni.get_stazioni()
for sensore in datamerged.columns[1:]:
location = s.loc[s['idsensore'] == sensore.split("-")[0], '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("\nKeyError: forse hai specificato un dataset che non esiste ?")
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()