#!/usr/bin/env python # coding: utf-8 # # Objet : Test opendata des données de qualité de l'air # # ## Objectif # # - valider sur des cas réels l'outil de traitement des "listes indexées" # - identifier les apports que pourraient avoir ce type d'outil # # ## Résultats # - gain de taille de fichier très important (15 Mo pour un fichier csv "quoté" et 11 Mo pour un fichier csv non "quoté" contre 0,9 Mo pour un fichier texte optimisé et 0,5 Mo pour un fichier binaire) ! # - on a donc un gain d'un facteur 10 à 20 sur le format texte # # ## Usages possibles # - à compléter # # ## Autres points # - chargement sur MongoDB à tester # - Outil de requète à tester # # données utilisées : https://files.data.gouv.fr/lcsqa/concentrations-de-polluants-atmospheriques-reglementes/temps-reel/2022/ # ## Présentation des données # # L'exemple concerne les mesures horaires de concentration de polluants de l'air pour différentes stations de mesure fixes. # # La structure de données mises à disposition est la suivante (principaux champs). # # > # > # # Les données sont découpées par fichier CSV d'une journée (49 000 lignes). Chaque fichier a une taille de 10,5 Mo, ce qui représente un volume annuel de 3,8 Go (18 millions de lignes). # ------ # ## Initialisation # - lecture des fichiers de 01/2022 issus de l'api (un fichier par jour) # In[1]: from pprint import pprint from collections import Counter from time import time from datetime import datetime import csv from util import util from observation import Sdataset, Sfield from copy import copy import pandas as pd chemin = 'https://raw.githubusercontent.com/loco-philippe/Environmental-Sensing/main/python/Validation/air/data_lcsqa/' # In[2]: data = [] nb_fichiers = 1 annee = 2022 mois = 1 jour = 1 for i in range(nb_fichiers): file = chemin + 'FR_E2_' + str(annee) + '-' + format(mois, '02d') +'-' + format(jour+i, '02d') +'.csv' data.append(pd.read_csv(file, sep=';')) data2 = pd.concat(data, ignore_index=True, join='inner') #data2[['Date de début','Date de fin']] = data2[['Date de début','Date de fin']].astype('datetime64') data2 = data2.astype('category') print('data2 : \n', len(data2), '\n') print(data2.iloc[0]) # In[3]: from json_ntv import Ntv t0 = time() ntv = Ntv.obj(data2) print(time()-t0) js = ntv.to_obj(encoded=True) print(len(js)) # ---- # ## objet Dataset # - l'initialisation aurait pu être effectuée à partir du fichier csv # - quelques indicateurs : # - nombre de données : 1 136 016 # - nombre de données différentes : 8 471 (ratio : 0,7 %) # - la taille minimale serait de 73 Ko (données csv "quotées") pour un maximum de 15,3 Mo (données csv "quotées") # In[4]: idxs2 = Sdataset(data2) print('idxs (len, lenlidx, sumcodec) : ', len(idxs2), len(idxs2.idxlen), sum(idxs2.idxlen)) idxs3 = Sdataset(idxs2) print(idxs3 == idxs2) # In[5]: t0=time() pprint(idxs2.category) print('\n') pprint(idxs2.groups) print('\n', idxs2.tree(), '\n') print(idxs2.tree(mode='diff')) print(time()-t0) # ## formats de base # In[6]: t0=time() js = idxs2.to_ntv(modecodec='full').to_obj(encoded=True) fullsize = len(js) print('fullsize', len(js), time()-t0) # In[7]: t0=time() idxs4 = Sdataset.from_ntv(js) print('new', len(idxs4), time()-t0) t0=time() verif = idxs4 == idxs2 print('controle égalité :', verif, time()-t0) # In[8]: t0=time() js = idxs2.to_ntv(modecodec='nokeys').to_obj(encoded=True) minsize = len(js) print('minsize', len(js), time()-t0) t0=time() js = idxs2.to_ntv(modecodec='nokeys').to_obj(encoded=True, format='cbor') print('mincborsize', len(js), time()-t0) # ---- # ## format default # - # In[9]: champ = idxs2.nindex t0=time() #js = idxs2.to_ntv(modecodec='default').to_obj(encoded=True) nt = idxs2.to_ntv(modecodec='default') print(time()-t0) js = nt.to_obj(encoded=True) print(time()-t0) defaultsize = len(js) print('defaultsize : ', defaultsize, time()-t0, '\n') print('indicator default : ', idxs2.indicator(fullsize, defaultsize), '\n') t0=time() pprint(champ('code site').couplinginfos(champ('Date de début'))) print('\n', idxs2.tree(mode='diff')) print('\nanalyse : ', time()-t0) # In[10]: print(idxs2.analysis.getmatrix(['Polluant', 'unité de mesure'])) notcoupl = champ('Polluant').coupling(champ('unité de mesure'), derived=True) print('nombre de non couplés : ', len(notcoupl)) print('\nliste des premières incohérences : ') liste = [(champ('Polluant')[i], champ('unité de mesure')[i]) for i in notcoupl[:2000]] pprint(set(liste), width=120) # In[11]: print(idxs2.analysis.getmatrix(['code site', 'nom site'])) notcoupl = champ('code site').coupling(champ('nom site'), derived=False) print('nombre de non couplés : ', len(notcoupl)) print('\nliste des premières incohérences : ') liste = [(champ('code site')[notcoupl[i]], champ('nom site')[notcoupl[i]]) for i in range(len(notcoupl))] pprint(set(liste), width=120) # In[12]: notcoupl = champ('nom site').coupling(champ('code site'), derived=False) print('nombre de non couplés : ', len(notcoupl)) print('\nliste des premières incohérences : ') liste = [(champ('code site')[notcoupl[i]], champ('nom site')[notcoupl[i]]) for i in range(len(notcoupl))] pprint(set(liste), width=120) # In[13]: print('controle égalité :', Sdataset.from_ntv(js) == idxs2) # ---- # ## Format optimisé # - # In[14]: idxs4.reindex() idxs4.coupling(param='distance', level=500) print(idxs4.tree()) t0=time() js = idxs4.to_ntv(modecodec='optimize').to_obj(encoded=True) optimizesize = len(js) print('optimizesize : ', optimizesize, time()-t0, '\n') print('indicator optimize : ', idxs2.indicator(fullsize, optimizesize), '\n') t0=time() js = idxs4.to_ntv(modecodec='optimize').to_obj(encoded=True, format='cbor') cborsize = len(js) print('cborsize : ', cborsize, time()-t0, '\n') print('indicator cbor : ', idxs2.indicator(fullsize, cborsize)) # In[15]: print('controle égalité :', Sdataset.from_ntv(js) == idxs2) # synthèse ancien: # # 1 fichier : full 14.4, def 3.8, opt 0.9 cbor 0.3 dic 7.5 500 # 3 fichiers : full 43.1, def 11.5, opt 2.5 cbor 1.3 dic 23.7 500 # 5 fichiers : full 71.9, def 19.3, opt 4.1 cbor 2.1 dic 41.1 500 # 10 fichiers : full 143.7, def 39.0, opt 8.2 cbor 4.0 dic 84.5 500 493 225 lignes # # synthèse ancien last: # # 1 fichier : full 3.3, def 0.2, opt 0.4 cbor 0.4 500 # # synthèse nouveau: # # 1 fichier : full 10.8, def 21.9, opt 5.5 cbor 8.3 500