Objet : Test opendata des données IRVE

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

  • l'outil fonctionne correctement (pas d'erreur identifiées, les temps de réponse restent néanmoins à améliorer).
  • l'analyse identifie des données anormales qui seraient à corriger (ou à expliquer) -> cf exemple dans la dernière cellule
  • le gain en taille de fichier varie de 50% (format texte non optimisé) à 80% (taille divisée par 5 !) dans un format optimisé et binaire. Ce niveau d'optimisation est tout à fait notable.
  • l'analyse permet de (re)trouver la logique de dépendance entre les colonnes

Usages possibles

  • les indicateurs utilisés permettent de qualifier le fichier csv et sont déployables simplement:
    • niveau de duplication des données
    • lien de dépendance entre les colonnes (permet un codage réduit des données).
  • l'usage de format de données moins gourmand (sans dégradation des données) peut également être intéressant à déployer
  • les schémas de données pourraient intégrer cette dépendance entre colonnes (ex. s'il y a une colonne "mois" et une colonne "trimestre", on peut indiquer que la colonne "trimestre" est "dérivée" de la colonne "mois", ou bien si on a une colonne "nom prénom" et une colonne "n° sécurité sociale", on peut indiquer que les deux colonnes sont "couplées".
  • la qualité des données peut faire l'objet d'un indicateur qui mesure l'écart (existant / attendu) des relations entre colonnes.

Autres points

  • capacité ok de l'objet Iindexset à traiter des structures de données importantes (50 colonnes)
  • indicateurs et fonctions de conversion pertinentes
  • temps de réponse de la fonction 'coupling' à regarder
  • tests complémentaires à effectuer sur d'autres jeux de données
  • représentation graphique de la structure des données à regarder
  • indicateur qualité à regarder

données utilisées : https://static.data.gouv.fr/resources/fichier-consolide-des-bornes-de-recharge-pour-vehicules-electriques/20220629-080611/consolidation-etalab-schema-irve-v-2.0.2-20220628.csv


Initialisation

  • lecture du fichier issu de l'api (quelques lignes incohérentes au niveau csv ont été éliminées au préalable)
In [32]:
from pprint import pprint
from collections import Counter
from time import time
import csv
import os
os.chdir('C:/Users/a179227/OneDrive - Alliance/perso Wx/ES standard/python ESstandard/ES')
from iindex import Iindex, util
from iindexset import Iindexset

chemin = 'C:/Users/a179227/OneDrive - Alliance/perso Wx/ES standard/python ESstandard/validation/irve/'

file = chemin + 'consolidation-etalab-schema-irve-v-2.0.2-20220606-propre.csv'

print('file size : ', os.stat(file).st_size)
file size :  7467244
In [33]:
t0 = time()
with open(file, newline='', encoding='utf-8') as f:
    reader = csv.reader(f, delimiter=';')
    names = next(reader)
    data = []
    for row in reader: data.append(row)
data2 = util.list(list(zip(*data)))
print('data', time()-t0)
data 0.5849692821502686

initialisation de l'objet Iindexset

  • l'initialisation pourrait être automatisée à partir du fichier csv
  • identification de 64 775 valeurs différentes sur un total de 11 163 x 49 valeurs ("taux d'unicité" de 12%)
  • la taille minimale serait de 1,4 Mo (données csv "quotées") pour un maximum de 9,6 Mo (données csv "quotées")
In [34]:
t0=time()
idxs = Iindexset.Iext(data2, names, fast=True)
print('idxs (len, lenlidx, sumcodec) : ', len(idxs), len(idxs.idxlen), sum(idxs.idxlen), time()-t0)
t0=time()
fullsize = len(idxs.to_obj(encoded=True, fullcodec=True))
print('fullsize', fullsize, time()-t0)
t0=time()
minsize = len(idxs.to_obj(encoded=True, defaultcodec=True, fullcodec=True))
print('minsize', minsize, time()-t0)
idxs (len, lenlidx, sumcodec) :  11163 49 64775 1.9536161422729492
fullsize 9615178 13.746973037719727
minsize 1388222 1.8562648296356201

format non optimisé

  • le "taux d'unicité" reste à 12% (pas de modification des index)
  • le "taux de codage" est de 30% (remplacement des données dupliquées par un entier)
  • le gain de taille de fichier par rapport à un fichier "quoté" est de 61%
  • l'analyse de la structure montre que les données sont principalement du type "linked" (non ou peu structuré)
  • quelques colonnes sont de type "derived". Par exemple les index longitude(43) et latitude(44) sont bien dérivés de l'index coordonneesXY(13)
  • le taux de couplage ("linkrate") pour chacun des index est très proche de 0, ce qui signifie que les données devraient être de type "derived" (lien de dépendance par exemple comme entre les trimestres et les mois) ou "coupled" (lien biunivoque).
In [35]:
t0=time()
defaultsize = len(idxs.to_obj(encoded=True, defaultcodec=True))
print('defaultsize', defaultsize, time()-t0)
print('indicator default : ', idxs.indicator(fullsize, defaultsize))
pprint(idxs.indexinfos(keys=['num', 'name', 'lencodec', 'parent', 'typecoupl'], base=True), width=120)
pprint(idxs.indexinfos(keys=['linkrate']))
defaultsize 3725037 2.2882091999053955
indicator default :  {'unique values': 64824, 'unicity level': 0.116, 'mean size': 5.287, 'object lightness': 0.307, 'gain': 0.613}
[{'lencodec': 481, 'name': '\ufeffnom_amenageur', 'num': 0, 'parent': 9, 'typecoupl': 'linked'},
 {'lencodec': 670, 'name': 'siren_amenageur', 'num': 1, 'parent': 9, 'typecoupl': 'linked'},
 {'lencodec': 388, 'name': 'contact_amenageur', 'num': 2, 'parent': 9, 'typecoupl': 'linked'},
 {'lencodec': 152, 'name': 'nom_operateur', 'num': 3, 'parent': 39, 'typecoupl': 'linked'},
 {'lencodec': 159, 'name': 'contact_operateur', 'num': 4, 'parent': 39, 'typecoupl': 'linked'},
 {'lencodec': 215, 'name': 'telephone_operateur', 'num': 5, 'parent': 13, 'typecoupl': 'linked'},
 {'lencodec': 764, 'name': 'nom_enseigne', 'num': 6, 'parent': 9, 'typecoupl': 'linked'},
 {'lencodec': 7060, 'name': 'id_station_itinerance', 'num': 7, 'parent': 15, 'typecoupl': 'linked'},
 {'lencodec': 3838, 'name': 'id_station_local', 'num': 8, 'parent': 16, 'typecoupl': 'linked'},
 {'lencodec': 4503, 'name': 'nom_station', 'num': 9, 'parent': 15, 'typecoupl': 'linked'},
 {'lencodec': 5, 'name': 'implantation_station', 'num': 10, 'parent': 8, 'typecoupl': 'linked'},
 {'lencodec': 4392, 'name': 'adresse_station', 'num': 11, 'parent': 13, 'typecoupl': 'linked'},
 {'lencodec': 2593, 'name': 'code_insee_commune', 'num': 12, 'parent': 9, 'typecoupl': 'linked'},
 {'lencodec': 4459, 'name': 'coordonneesXY', 'num': 13, 'parent': 9, 'typecoupl': 'linked'},
 {'lencodec': 32, 'name': 'nbre_pdc', 'num': 14, 'parent': 7, 'typecoupl': 'linked'},
 {'lencodec': 10322, 'name': 'id_pdc_itinerance', 'num': 15, 'parent': 15, 'typecoupl': 'crossed'},
 {'lencodec': 7095, 'name': 'id_pdc_local', 'num': 16, 'parent': 15, 'typecoupl': 'linked'},
 {'lencodec': 61, 'name': 'puissance_nominale', 'num': 17, 'parent': 37, 'typecoupl': 'linked'},
 {'lencodec': 9, 'name': 'prise_type_ef', 'num': 18, 'parent': 16, 'typecoupl': 'linked'},
 {'lencodec': 8, 'name': 'prise_type_2', 'num': 19, 'parent': 23, 'typecoupl': 'linked'},
 {'lencodec': 8, 'name': 'prise_type_combo_ccs', 'num': 20, 'parent': 19, 'typecoupl': 'linked'},
 {'lencodec': 7, 'name': 'prise_type_chademo', 'num': 21, 'parent': 22, 'typecoupl': 'linked'},
 {'lencodec': 8, 'name': 'prise_type_autre', 'num': 22, 'parent': 20, 'typecoupl': 'linked'},
 {'lencodec': 9, 'name': 'gratuit', 'num': 23, 'parent': 15, 'typecoupl': 'linked'},
 {'lencodec': 9, 'name': 'paiement_acte', 'num': 24, 'parent': 13, 'typecoupl': 'linked'},
 {'lencodec': 8, 'name': 'paiement_cb', 'num': 25, 'parent': 23, 'typecoupl': 'linked'},
 {'lencodec': 9, 'name': 'paiement_autre', 'num': 26, 'parent': 39, 'typecoupl': 'linked'},
 {'lencodec': 128, 'name': 'tarification', 'num': 27, 'parent': 9, 'typecoupl': 'linked'},
 {'lencodec': 3, 'name': 'condition_acces', 'num': 28, 'parent': 11, 'typecoupl': 'derived'},
 {'lencodec': 8, 'name': 'reservation', 'num': 29, 'parent': 39, 'typecoupl': 'linked'},
 {'lencodec': 140, 'name': 'horaires', 'num': 30, 'parent': 11, 'typecoupl': 'linked'},
 {'lencodec': 5, 'name': 'accessibilite_pmr', 'num': 31, 'parent': 16, 'typecoupl': 'linked'},
 {'lencodec': 97, 'name': 'restriction_gabarit', 'num': 32, 'parent': 9, 'typecoupl': 'linked'},
 {'lencodec': 7, 'name': 'station_deux_roues', 'num': 33, 'parent': 13, 'typecoupl': 'derived'},
 {'lencodec': 3, 'name': 'raccordement', 'num': 34, 'parent': 16, 'typecoupl': 'linked'},
 {'lencodec': 1371, 'name': 'num_pdl', 'num': 35, 'parent': 13, 'typecoupl': 'linked'},
 {'lencodec': 1102, 'name': 'date_mise_en_service', 'num': 36, 'parent': 15, 'typecoupl': 'linked'},
 {'lencodec': 101, 'name': 'observations', 'num': 37, 'parent': 39, 'typecoupl': 'linked'},
 {'lencodec': 269, 'name': 'date_maj', 'num': 38, 'parent': 39, 'typecoupl': 'linked'},
 {'lencodec': 385, 'name': 'last_modified', 'num': 39, 'parent': 6, 'typecoupl': 'linked'},
 {'lencodec': 294, 'name': 'datagouv_dataset_id', 'num': 40, 'parent': 39, 'typecoupl': 'derived'},
 {'lencodec': 385, 'name': 'datagouv_resource_id', 'num': 41, 'parent': 39, 'typecoupl': 'coupled'},
 {'lencodec': 122, 'name': 'datagouv_organization_or_owner', 'num': 42, 'parent': 40, 'typecoupl': 'derived'},
 {'lencodec': 4448, 'name': 'consolidated_longitude', 'num': 43, 'parent': 13, 'typecoupl': 'derived'},
 {'lencodec': 4429, 'name': 'consolidated_latitude', 'num': 44, 'parent': 13, 'typecoupl': 'derived'},
 {'lencodec': 1697, 'name': 'consolidated_code_postal', 'num': 45, 'parent': 9, 'typecoupl': 'linked'},
 {'lencodec': 2511, 'name': 'consolidated_commune', 'num': 46, 'parent': 9, 'typecoupl': 'linked'},
 {'lencodec': 3, 'name': 'consolidated_is_lon_lat_correct', 'num': 47, 'parent': 28, 'typecoupl': 'linked'},
 {'lencodec': 3, 'name': 'consolidated_is_code_insee_verified', 'num': 48, 'parent': 45, 'typecoupl': 'linked'}]
[{'linkrate': 6.014508845954549e-06},
 {'linkrate': 3.319494361340903e-06},
 {'linkrate': 2.8691753588334162e-06},
 {'linkrate': 0.00015481207534187667},
 {'linkrate': 0.00011507479861910241},
 {'linkrate': 4.7158639567565756e-05},
 {'linkrate': 4.162071652246398e-05},
 {'linkrate': 5.764242640688488e-07},
 {'linkrate': 7.126192190832081e-06},
 {'linkrate': 5.939361188133914e-06},
 {'linkrate': 0.0003908285565398645},
 {'linkrate': 2.0940302313612285e-06},
 {'linkrate': 7.710908776864807e-07},
 {'linkrate': 2.1918491704897e-06},
 {'linkrate': 8.224435712327516e-05},
 {'linkrate': 1.0},
 {'linkrate': 3.8784955829124845e-06},
 {'linkrate': 0.013201320132013201},
 {'linkrate': 0.0004580690627202255},
 {'linkrate': 0.12698412698412698},
 {'linkrate': 0.08928571428571429},
 {'linkrate': 0.0625},
 {'linkrate': 0.08928571428571429},
 {'linkrate': 6.0550280953303626e-05},
 {'linkrate': 0.00011213276519398969},
 {'linkrate': 0.07936507936507936},
 {'linkrate': 0.0012987012987012987},
 {'linkrate': 3.147507960572217e-05},
 {'linkrate': 0.0},
 {'linkrate': 0.00037105751391465676},
 {'linkrate': 3.931281204544561e-05},
 {'linkrate': 7.047216349541931e-05},
 {'linkrate': 1.156636316529721e-05},
 {'linkrate': 0.0},
 {'linkrate': 7.047216349541931e-05},
 {'linkrate': 9.658150578752397e-06},
 {'linkrate': 1.7422642148961477e-05},
 {'linkrate': 0.0004155844155844156},
 {'linkrate': 0.0015603799185888738},
 {'linkrate': 0.0003544938917975567},
 {'linkrate': 0.0},
 {'linkrate': 0.0},
 {'linkrate': 0.0},
 {'linkrate': 0.0},
 {'linkrate': 0.0},
 {'linkrate': 7.856397621711312e-07},
 {'linkrate': 6.193303623171095e-07},
 {'linkrate': 0.3333333333333333},
 {'linkrate': 0.0002946375957572186}]

couplage

  • transformation des index qui devraient être couplés en index couplés (tous les index sont bien maintenant de type "derived")
In [36]:
t0=time()
infos = idxs.coupling(fast=True)
print('coupling', time()-t0)
pprint(idxs.indexinfos(keys=['num', 'name', 'parent', 'typecoupl']), width=120)
pprint(idxs.indexinfos(keys=['num', 'name', 'parent', 'typecoupl']), width=120)
coupling 55.95050048828125
[{'name': '\ufeffnom_amenageur', 'num': 0, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'siren_amenageur', 'num': 1, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'contact_amenageur', 'num': 2, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'nom_operateur', 'num': 3, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'contact_operateur', 'num': 4, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'telephone_operateur', 'num': 5, 'parent': 13, 'typecoupl': 'derived'},
 {'name': 'nom_enseigne', 'num': 6, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'id_station_itinerance', 'num': 7, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'id_station_local', 'num': 8, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'nom_station', 'num': 9, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'implantation_station', 'num': 10, 'parent': 8, 'typecoupl': 'derived'},
 {'name': 'adresse_station', 'num': 11, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'code_insee_commune', 'num': 12, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'coordonneesXY', 'num': 13, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'nbre_pdc', 'num': 14, 'parent': 7, 'typecoupl': 'derived'},
 {'name': 'id_pdc_itinerance', 'num': 15, 'parent': 15, 'typecoupl': 'crossed'},
 {'name': 'id_pdc_local', 'num': 16, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'puissance_nominale', 'num': 17, 'parent': 37, 'typecoupl': 'derived'},
 {'name': 'prise_type_ef', 'num': 18, 'parent': 16, 'typecoupl': 'derived'},
 {'name': 'prise_type_2', 'num': 19, 'parent': 20, 'typecoupl': 'derived'},
 {'name': 'prise_type_combo_ccs', 'num': 20, 'parent': 30, 'typecoupl': 'derived'},
 {'name': 'prise_type_chademo', 'num': 21, 'parent': 22, 'typecoupl': 'derived'},
 {'name': 'prise_type_autre', 'num': 22, 'parent': 20, 'typecoupl': 'derived'},
 {'name': 'gratuit', 'num': 23, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'paiement_acte', 'num': 24, 'parent': 13, 'typecoupl': 'derived'},
 {'name': 'paiement_cb', 'num': 25, 'parent': 23, 'typecoupl': 'derived'},
 {'name': 'paiement_autre', 'num': 26, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'tarification', 'num': 27, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'condition_acces', 'num': 28, 'parent': 11, 'typecoupl': 'derived'},
 {'name': 'reservation', 'num': 29, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'horaires', 'num': 30, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'accessibilite_pmr', 'num': 31, 'parent': 16, 'typecoupl': 'derived'},
 {'name': 'restriction_gabarit', 'num': 32, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'station_deux_roues', 'num': 33, 'parent': 11, 'typecoupl': 'derived'},
 {'name': 'raccordement', 'num': 34, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'num_pdl', 'num': 35, 'parent': 13, 'typecoupl': 'derived'},
 {'name': 'date_mise_en_service', 'num': 36, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'observations', 'num': 37, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'date_maj', 'num': 38, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'last_modified', 'num': 39, 'parent': 6, 'typecoupl': 'derived'},
 {'name': 'datagouv_dataset_id', 'num': 40, 'parent': 41, 'typecoupl': 'derived'},
 {'name': 'datagouv_resource_id', 'num': 41, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'datagouv_organization_or_owner', 'num': 42, 'parent': 40, 'typecoupl': 'derived'},
 {'name': 'consolidated_longitude', 'num': 43, 'parent': 13, 'typecoupl': 'derived'},
 {'name': 'consolidated_latitude', 'num': 44, 'parent': 13, 'typecoupl': 'derived'},
 {'name': 'consolidated_code_postal', 'num': 45, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'consolidated_commune', 'num': 46, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'consolidated_is_lon_lat_correct', 'num': 47, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'consolidated_is_code_insee_verified', 'num': 48, 'parent': 45, 'typecoupl': 'derived'}]
[{'name': '\ufeffnom_amenageur', 'num': 0, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'siren_amenageur', 'num': 1, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'contact_amenageur', 'num': 2, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'nom_operateur', 'num': 3, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'contact_operateur', 'num': 4, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'telephone_operateur', 'num': 5, 'parent': 13, 'typecoupl': 'derived'},
 {'name': 'nom_enseigne', 'num': 6, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'id_station_itinerance', 'num': 7, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'id_station_local', 'num': 8, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'nom_station', 'num': 9, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'implantation_station', 'num': 10, 'parent': 8, 'typecoupl': 'derived'},
 {'name': 'adresse_station', 'num': 11, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'code_insee_commune', 'num': 12, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'coordonneesXY', 'num': 13, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'nbre_pdc', 'num': 14, 'parent': 7, 'typecoupl': 'derived'},
 {'name': 'id_pdc_itinerance', 'num': 15, 'parent': 15, 'typecoupl': 'crossed'},
 {'name': 'id_pdc_local', 'num': 16, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'puissance_nominale', 'num': 17, 'parent': 37, 'typecoupl': 'derived'},
 {'name': 'prise_type_ef', 'num': 18, 'parent': 16, 'typecoupl': 'derived'},
 {'name': 'prise_type_2', 'num': 19, 'parent': 20, 'typecoupl': 'derived'},
 {'name': 'prise_type_combo_ccs', 'num': 20, 'parent': 30, 'typecoupl': 'derived'},
 {'name': 'prise_type_chademo', 'num': 21, 'parent': 22, 'typecoupl': 'derived'},
 {'name': 'prise_type_autre', 'num': 22, 'parent': 20, 'typecoupl': 'derived'},
 {'name': 'gratuit', 'num': 23, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'paiement_acte', 'num': 24, 'parent': 13, 'typecoupl': 'derived'},
 {'name': 'paiement_cb', 'num': 25, 'parent': 23, 'typecoupl': 'derived'},
 {'name': 'paiement_autre', 'num': 26, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'tarification', 'num': 27, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'condition_acces', 'num': 28, 'parent': 11, 'typecoupl': 'derived'},
 {'name': 'reservation', 'num': 29, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'horaires', 'num': 30, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'accessibilite_pmr', 'num': 31, 'parent': 16, 'typecoupl': 'derived'},
 {'name': 'restriction_gabarit', 'num': 32, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'station_deux_roues', 'num': 33, 'parent': 11, 'typecoupl': 'derived'},
 {'name': 'raccordement', 'num': 34, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'num_pdl', 'num': 35, 'parent': 13, 'typecoupl': 'derived'},
 {'name': 'date_mise_en_service', 'num': 36, 'parent': 15, 'typecoupl': 'derived'},
 {'name': 'observations', 'num': 37, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'date_maj', 'num': 38, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'last_modified', 'num': 39, 'parent': 6, 'typecoupl': 'derived'},
 {'name': 'datagouv_dataset_id', 'num': 40, 'parent': 41, 'typecoupl': 'derived'},
 {'name': 'datagouv_resource_id', 'num': 41, 'parent': 39, 'typecoupl': 'derived'},
 {'name': 'datagouv_organization_or_owner', 'num': 42, 'parent': 40, 'typecoupl': 'derived'},
 {'name': 'consolidated_longitude', 'num': 43, 'parent': 13, 'typecoupl': 'derived'},
 {'name': 'consolidated_latitude', 'num': 44, 'parent': 13, 'typecoupl': 'derived'},
 {'name': 'consolidated_code_postal', 'num': 45, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'consolidated_commune', 'num': 46, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'consolidated_is_lon_lat_correct', 'num': 47, 'parent': 9, 'typecoupl': 'derived'},
 {'name': 'consolidated_is_code_insee_verified', 'num': 48, 'parent': 45, 'typecoupl': 'derived'}]

Format optimisé

  • le "taux d'unicité" se dégrade légèrement (passage de 11,6% à 12,1%) par l'ajout d'index supplémentaires
  • le "taux de codage" par contre passe de 30% à 16% de par l'optimisation
  • le gain de taille de fichier par rapport à un fichier "quoté" est maintenant de 74%
  • l'utilisation d'un format binaire (codage CBOR pour Concise Binary Object Representation RFC 8949) permet d'améliorer encore le gain de taille de fichier (82%)
In [37]:
t0=time()
optimizesize = len(idxs.to_obj(indexinfos=infos, encoded=True))
print('optimizesize ', optimizesize, time()-t0)
print('indicator optimize : ', idxs.indicator(fullsize, optimizesize))
t0=time()
js = idxs.to_obj(indexinfos=infos, encoded=True, encode_format='cbor')
cborsize = len(js)
print('cborsize', cborsize, time()-t0)
print('indicator cbor : ', idxs.indicator(fullsize, cborsize))
optimizesize  2495885 10.116098403930664
indicator optimize :  {'unique values': 67357, 'unicity level': 0.121, 'mean size': 2.721, 'object lightness': 0.158, 'gain': 0.74}
cborsize 1717876 10.97364854812622
indicator cbor :  {'unique values': 67357, 'unicity level': 0.121, 'mean size': 1.136, 'object lightness': 0.066, 'gain': 0.821}

Intégrité

  • la transformation inverse des données binaires permet de vérifier qu'on retombe bien sur les mêmes données (pas de dégradation)
In [38]:
t0=time()
idxs2 = Iindexset.from_obj(js)
print('fromcbor', len(idxs2), time()-t0)
t0=time()
verif = idxs2 == idxs
print('controle égalité :', verif, time()-t0)
fromcbor 11163 3.348214864730835
controle égalité : True 0.24997305870056152

Exemple de données anormales

  • l'index coordonneesXY(13) est lié à l'index nom_station(9) avec un taux de couplage très faible, par ailleurs, le nombre de valeurs de ces deux index sont très proches (4503 nom_station pour 4459 coordonneesXY), ce qui signifie que dans la majorité des cas, on associe de façon unique une station et une position
  • les exemples ci-dessous montrent les écarts les plus important :
    • la position [1.106329, 49.474202] est associée à 10 stations
    • la station Camping Arinella est associée à 5 positions
In [41]:
print('Couplage entre ', idxs[13].name, ' et ', idxs[9].name, ' : ', idxs[13].couplinginfos(idxs[9])['typecoupl'])
infosdefault = idxs[9].couplinginfos(idxs[13], default=True)
print('Ecart : ', infosdefault['disttomin'], 'positions sur ', infosdefault['distmin'], '\n') # moins de 1%
nom_station = idxs[9].tostdcodec(full=False)
coordonneesXY = idxs[13].tostdcodec(full=False) 
coordonneesXY.coupling(nom_station)
c = Counter(coordonneesXY.codec).most_common(5)
print('les 5 positions avec le plus de stations: ', c, '\n')
print('liste des stations associées à la position', c[0][0], ' : ', 
      [nom_station[i] for i in coordonneesXY.recordfromvalue(c[0][0])], '\n')
coordonneesXY = idxs[13].tostdcodec(full=False)
nom_station.coupling(coordonneesXY)
c = Counter(nom_station.codec).most_common(5)
print('les 5 stations avec le plus de positions: ', c, '\n')
print('liste des positions associées à la station', c[0][0], ' : ', 
      [coordonneesXY[i] for i in nom_station.recordfromvalue(c[0][0])])
Couplage entre  coordonneesXY  et  nom_station  :  derived
Ecart :  44 positions sur  4503 

les 5 positions avec le plus de stations:  [('[1.106329, 49.474202]', 10), ('[1.313367, 49.137233]', 6), ('[3.080477, 50.675889]', 6), ('[2.523685, 48.9908]', 5), ('[3.1557445, 50.5161745]', 4)] 

liste des stations associées à la position [1.106329, 49.474202]  :  ['SCH01', 'SCH10', 'SCH09', 'SCH07', 'SCH06', 'SCH05', 'SCH04', 'SCH03', 'SCH02', 'SCH08'] 

les 5 stations avec le plus de positions:  [('Camping Arinella', 5), ('GUERET', 4), ('Noues de Sienne, Le Bourg', 3), ('PONTORSON - aire de covoiturage', 2), ('Beaumont Saint-Cyr', 2)] 

liste des positions associées à la station Camping Arinella  :  ['[9.445075, 41.995246]', '[9.445074, 41.995246]', '[9.445073, 41.995246]', '[9.445072, 41.995246]', '[9.445071, 41.995246]']