{ "cells": [ { "cell_type": "markdown", "id": "73455583", "metadata": {}, "source": [ "# Quel avenir pour le format CSV ?\n", "\n", "Le format CSV est le format le plus utilisé pour partager des données tabulaires. \n", " \n", "Il a été standardisé en 2005 (RFC 4180) et est accessible depuis la majorité des outils traitant des ensembles de données structurées sous forme de listes, d'arborescences ou de tableaux multi-dimensionnels. \n", " \n", "Pourtant ce format très pauvre d'un point de vue sémantique présente de nombreuses limitations et semble mal adapté aux besoins d'échanges de données.\n", "\n", "Cette note a pour objet de présenter les alternatives possibles à ce format pour un meilleur échange de données." ] }, { "cell_type": "markdown", "id": "88f9b50c", "metadata": {}, "source": [ "## 1 - Données tabulaires\n", "Les données tabulaires sont les données représentées sous la forme de tableaux composés de lignes et de colonnes. Ces deux notions ne sont pas équivalentes, les colonnes (ou champs) représentent la 'sémantique' des données et les lignes représentent les objets décrits suivant la structuration définie par les colonnes.\n", "\n", "Si l'on observe maintenant comment sont utilisés les tableaux, on peut identifier trois usages principaux :\n", "\n", "- la classification : Il s'agit de regrouper les objets par catégories afin de pouvoir par exemple en faire une exploitation statistique, \n", "- le croisement : Il consiste à représenter toutes les combinaisons entre deux paramètres comme par exemple dans les représentations matricielles \n", "- la caractérisation : Elle correspond à la documentation de propriétés définies.\n", "\n", "> *Prenons un exemple :*\n", ">\n", "|id|produit|aliment\t|quantité\t|prix|validité|disponibilité|\n", "|:------:|:------:|:------:|:------:|:------:|:------:|:------:|\n", "|11|pomme|fruit\t|sachet 1 kg\t|1\t|du 1/7/2022 au 31/12/2022|oui|\n", "|12|pomme|fruit\t|carton 10 kg\t|9|du 1/7/2022 au 31/12/2022|oui|\n", "|13|orange|fruit\t|sachet 1 kg|2|du 1/7/2022 au 31/12/2022|fin 2022|\n", "|14|orange|fruit\t|carton 10 kg\t|18\t|du 1/7/2022 au 31/12/2022|fin 2022|\n", "|15|piment|légume\t|sachet 1 kg\t|1.5|du 1/7/2022 au 31/12/2022|oui|\n", "|16|piment|légume\t|carton 10 kg|13|du 1/7/2022 au 31/12/2022|fin 2022|\n", "|17|banane|fruit\t|sachet 1 kg\t|0.5|du 1/7/2022 au 31/12/2022|oui|\n", "|18|banane|fruit\t|carton 10 kg\t|4|du 1/7/2022 au 31/12/2022|oui|\n", ">\n", ">\n", ">*Il s'agit d'une liste de prix de différents aliments en fonction d'un conditionnement pour l'année 2022.*\n", ">\n", "> *On retrouve ici :*\n", "> - *la classification : entre les produits et les aliments,* \n", "> - *le croisement : entre les produits et les quantités,*\n", "> - *la caractérisation : la disponibilité du produit*\n", "\n", "On peut noter que les deux usages de classification et de croisement conduisent à dupliquer fortement les informations avec les risques d'erreurs associés.\n" ] }, { "cell_type": "markdown", "id": "01fe3c15", "metadata": {}, "source": [ "## 2 - Format CSV\n", "Le format CSV (Comma-Separated Values) est un format texte (principalement ASCII) dans lequel les données sont structurées en lignes. Chaque ligne contient un nombre identique de champs. Chaque champ est une chaîne de caractères représentant une donnée à partager. \n", "Il s'agit donc d'un format totalement adapté aux données tabulaires. \n", " \n", "Plusieurs options de représentation sont possibles :\n", "- présence d'un entête contenant le nom des champs,\n", "- utilisation de formats de caractères autres qu'ASCII\n", "- utilisation de double-quotes (\") pour délimiter les champs\n", "- séparateur de champs alternatifs à la virgule (ex. point-virgule) (hors standard RFC 4180 mais très utilisé pour éviter la confusion avec la virgule des \"nombres à virgule\"))\n", " \n", "Voyons maintenant quels sont les avantages et inconvénients de ce format.\n", "\n", "### Avantages\n", "- Le premier avantage de ce format est sa simplicité. \n", "- Le deuxième avantage est sa disponibilité sur tous type de plateforme et de logiciel. \n", "- Le troisième avantage est qu'il s'agit d'un format texte, il peut donc être consulté par tous dans un simple éditeur de texte. \n", "- Le quatrième avantage est sa lisibilité puisque la structure des données (lignes et champs) est l'image exacte de ce qui est restitué dans les tableurs (principaux outils de traitement des données tabulaires), elle est donc facile à interpréter. \n", "\n", "### Inconvénients\n", "- Le premier inconvenient découle de l'absence de sémantique des données. Par exemple, il n'est pas possible de distinguer une valeur numérique d'une valeur textuelle (le chiffre 1 et le caractère 1 sont représenté de la même façon). Il est également difficile de jongler entre différents codages (ASCII / Unicode).\n", "- Le second inconvénient est lié à la non prise en compte des structures tabulaires identifiées dans le premier paragraphe, ce qui conduit à dupliquer les données et ainsi à des fichiers de taille importante. \n", "- Le troisième inconvénient est que ce format n'est pas réversible (la lecture d'un fichier CSV ne garantit pas de retouver les données d'origine). Il s'agit plus d'un format d'export que d'un format d'échange. \n", "- Le quatrième inconvénient est lié à l'absence de prise en compte d'un \"schéma de données\" minimal (le nom des colonnes est optionnel, le typage des colonnes n'est pas défini). \n", "- Le cinquième inconvénient est que ce format est adapté pour les fichiers mais ne l'est pas pour les échanges de données par API\n", " \n", "Plus généralement, le format CSV est considéré comme un format obsolète et ne permettant pas une réelle interopérabilité des données. \n", " \n", "Le [Référentiel Général d'Interopérabilité (RGI)](https://www.numerique.gouv.fr/uploads/Referentiel_General_Interoperabilite_V2.pdf) dans sa dernière version de 2015 qualifie ainsi le format CSV :\n", ">\n", ">*Cotation : En fin de vie* *\n", ">\n", ">*CSV est un format informatique d’échange de données ouvert représentant des données\n", "tabulaires sous forme de valeurs séparées par des virgules.\n", "D’autres variantes de séparateur de champ peuvent être utilisées, notamment lorsque la virgule\n", "est un élément signifiant d’une donnée. L’utilisation des séparateurs de champs doit donc être\n", "utilisée avec circonspection et adaptée au contexte sous peine de rendre le fichier inexploitable.\n", "Ce format est retenu dans le RGI par exception. Il doit être évité car il n’est pas nécessairement\n", "interopérable d’une plateforme à l’autre, la spécification précisant uniquement le format des fins\n", "de ligne mais ne précisant pas l’encodage à utiliser pour le texte en lui-même et pour les\n", "séparateurs (la RFC mentionne uniquement un encodage US-ASCII).*\n", "> \n", ">*Note importante : Le standard CSV est au statut **recommandé uniquement** pour les échanges\n", "entre application et utilisateur. Pour tous les autres cas, il est considéré en « fin de vie ». Le\n", "standard XML est à privilégier pour les échanges entre applications ou systèmes, qui n’impliquent\n", "donc pas d’utilisateurs.*\n", "\n", "Son remplacement par un format plus adapté est devenu une priorité. \n" ] }, { "cell_type": "markdown", "id": "dbe419ba", "metadata": {}, "source": [ "## 3 - Formats alternatifs\n", "\n", "Avant d'examiner les formats alternatifs, il convient de définir des critères d'évaluation.\n", "\n", "### critères de sélection\n", "Au vu de des avantages et inconvénients identifiés au chapître précédent, on peut définir un premier ensemble de critères à respecter pour un potentiel successeur au format CSV:\n", "- simplicité\n", "- disponibilité multi-plateformes\n", "- format texte\n", "- interprétation aisée\n", "- niveau sémantique important (ex. date, intervalles, coordonnées géographiques)\n", "- volume de données faible\n", "- réversibilité \n", "- lisibilité de la structure des données\n", "- usage fichier et API\n", "- intégration des métadonnées (ex. schéma de données)\n", "- temps de réponse faible en lecture et écriture\n", "\n", "### candidats\n", "Pour identifier les candidats potentiels, nous pouvons examiner la liste des formats d'import/export proposés par [Pandas](https://pandas.pydata.org/docs/user_guide/io.html) (pandas est la principale application open source scientifique pour les données tabulaires). \n", "19 formats sont identifiés. Parmi ceux-ci, seuls 6 sont des formats texte : CSV, Fixed-Width text file, JSON, HTML, LaTeX, XML, Local clipboard auxquels nous pouvons ajouter YAML. \n", "\n", "Les formats binaires sont les plus nombreux et répondent à des attentes de performances et d'accessibilité pour des structures de taille importante (ex. promotion du format [parquet](https://www.icem7.fr/cartographie/parquet-devrait-remplacer-le-format-csv/) pour remplacer le format CSV). \n", "Les formats Fixed-Width text file et Local clipboard sont des formats similaires au format csv et avec des limitations plus importantes. Ils ne sont donc pas à retenir. \n", "Le format LaTeX est un format d'export uniquement (pour Pandas) et n'est pas vraiment adapté. \n", "Les formats HTML et XML sont des formats à 'balises', ce qui conduit à ajouter une quantité de données de structure importante. Ils sont par ailleurs moins lisibles qu'un format CSV. \n", "Le format YAML est un format qui étend la structuration définie pour JSON (ex. commentaires, références) mais est également moins compact que le format CSV. \n", "\n", "Le seul candidat qui répond à la majorité des critères définis est le format JSON:\n", "- simplicité : les entités manipulées sont limitées à 6 types d'objets\n", "- disponibilité multi-plateformes : pour chaque langage, les objets JSON sont transposables et les codeurs/decodeurs JSON sont également disponibles\n", "- format texte: oui\n", "- interprétation aisée: dépend du mode de représentation retenu\n", "- niveau sémantique : limité à 6 types d'entités mais les types composés (object, array) permettent de représenter des objets complexes\n", "- taille de fichier faible: La grammaire JSON introduit peu de données supplémentaires (séparateurs et délimiteurs d'entités)\n", "- réversibilité: oui sous réserve d'un bon codage des données élémentaires\n", "- lisibilité de la structure des données: oui, les types composés permettent une restitution lisible\n", "- usage fichier et API: oui, JSON est le format retenu (avec XML) pour les API REST (majorité des API).\n", "- métadonnées: Les métadonnées descriptives ou complémentaires d'un jeu de données tabulaires sont déjà fréquemment paratgées dans un format JSON (ex. schémas de données). L'intégration des métadonnées est donc aisée.\n", "- temps de réponse faible en lecture et écriture: dépend du mode de représentation retenu" ] }, { "cell_type": "markdown", "id": "cdf8fd44", "metadata": {}, "source": [ "## 4 - Première conclusion\n", "\n", "La rapide analyse effectuée ci-dessus (qui demande à être confortée par une étude complète) permet de tirer de premières conclusions :\n", "\n", "1. les structures tabulaires sont omniprésentes notamment dans le cadre open-data. Un standard d'échange pour ces structures est donc indispensable.\n", "2. le format CSV n'est plus un format pérenne, on ne peut donc pas \"faire l'impasse\" d'une réflexion sur le choix d'un standard d'échange alternatif.\n", "3. le format JSON est le candidat le plus prometteur.\n", "\n", "Ces conclusions permettent de définir une orientation, par contre elles ne sont pas suffisantes pour définir un successeur au format CSV. En effet, le format JSON est un langage de description de données, ce n'est pas un format d'échange de données tabulaires (cf standard ECMA-404 de 2017) :\n", "\n", "> *The JSON syntax is not a specification of a complete data interchange. Meaningful data interchange requires agreement between a producer and consumer on the semantics attached to a particular use of the JSON syntax. What JSON does provide is the syntactic framework to which such semantics can be attached.*\n", "\n", "Le chapitre suivant apporte un éclairage sur la définition d'un format JSON dédié aux données tabulaires.\n" ] }, { "cell_type": "markdown", "id": "8d783d49", "metadata": {}, "source": [ "## 5 - Quel JSON pour les données tabulaires ?\n", "\n", "### Format JSON\n", "Le format JSON est décrit dans les normes RFC 8259 et conjointement ECMA-404 de décembre 2017. Ce format a été créé en 2001, il est maintenant dans une version qui ne devrait plus évoluer. \n", "\n", "Il est construit autour de 7 entités :\n", "- deux entités composées :\n", " - `object` ensemble de paires « clé (string) / valeur (entité) »\n", " - `array` liste ordonnée d'entités\n", "- deux entités de base :\n", " - `string` chaîne de caractères unicode UTF-8\n", " - `number` valeur numérique codée sous forme de digits\n", "- trois entités littérales :\n", " - `false` et `true` valeurs booléennes,\n", " - valeur `null`\n", "\n", "Le format JSON a donné lieu à des formats dérivés comme par exemple GeoJSON pour les données géographiques, CBOR / BSON / UBJSON pour les formats binaires, JSON Schema pour les \"schema de données\", JSON-LD pour les structures du \"web sémantique\"...\n", "\n", "### Représentation basique\n", "Le choix d'une représentation JSON pour les données tabulaires n'est pas simple et de nombreuses options sont possibles. A titre d'exemple, Pandas propose 6 représentations différentes pour un même 'DataFrame' (dénomination pandas d'un tableau) !\n", "\n", "#### représentation matricielle\n", "La représentation la plus simple est la représentation matricielle \"array of arrays\" avec deux options \n", "- par lignes : les données d'une même ligne sont dans un même `array`,\n", "- par colonnes : les données d'une même colonne sont dans un même `array`\n", " \n", "Les représentations par lignes sont privilégiées dans les représentations dynamiques lorsqu'on fait évoluer le nombre de lignes.\n", "Les représentations par colonnes sont privilégiées dans le traitement des représentations statiques. Elles permettent de regrouper les données d'un même type afin d'en optimiser le format.\n", "\n", "Dans le cas présent d'un format d'échange, la représentation par colonne est à privilégier.\n", "\n", "> *La représentation JSON des deux premières colonnes de l'exemple du chapitre 1 est alors la suivante :*\n", "> \n", ">```python\n", ">[ [ \"id\", 11, 12, 13, 14, 15, 16, 17, 18 ],\n", "> [ \"produit\", \"pomme\", \"pomme\", \"orange\", \"orange\", \"piment\", \"piment\", \"banane\", \"banane\" ] ]\n", ">```\n", ">\n", "\n", "Cette représentation est équivalente à celle d'un format CSV.\n", "\n", "*Nota : Cette option de représentation par colonnes plutôt que par lignes peut sembler contre-intuitive puisqu'elle ne permet plus d'avoir une vue globale d'un objet qui a été enregistré dans le tableau (une ligne), par contre elle permet une meilleure visibilité de l'organisation et de la structuration des données. Par ailleurs, cette vision globale par objet (ligne) est difficle à obtenir pour des tableaux avec un nombre important de colonnes, ce qui nécessite le recours à des outils complémentaires.*\n", "\n", "#### entête\n", "Dans la majorité des utilisations, les colonnes présentent un entête qui précise le nom du champ et éventuellement le type de données. Cette information est à rendre explicite en la sortant de l'objet `array`. \n", " \n", "Dans les représentations Pandas et R, la représentation devient un 'array of objects' :\n", "\n", ">```python\n", ">[ { \"id\": [ 11, 12, 13, 14, 15, 16, 17, 18 ] },\n", "> { \"produit\": [\"pomme\", \"pomme\", \"orange\", \"orange\", \"piment\", \"piment\", \"banane\", \"banane\" ] } ]\n", ">```\n", "> \n", "\n", "Elle peut également rester dans une structure de type 'array of arrays':\n", "\n", ">```python\n", ">[ [ \"id\", [ 11, 12, 13, 14, 15, 16, 17, 18 ] ],\n", "> [ \"produit\", [\"pomme\", \"pomme\", \"orange\", \"orange\", \"piment\", \"piment\", \"banane\", \"banane\" ] ] ]\n", ">```\n", "\n", "Cette deuxième approche est préférable si l'on veut également intégrer un typage des colonnes (comme par exemple pour les dates) : \n", "\n", ">```python\n", ">[ [ {\"id\": \"integer\"}, [ 11, 12, 13, 14, 15, 16, 17, 18 ] ],\n", "> [ {\"produit\": \"string\"}, [\"pomme\", \"pomme\", \"orange\", \"orange\", \"piment\", \"piment\", \"banane\", \"banane\" ]]]\n", ">```\n", "> \n", " \n", "\n", "### Représentation unique\n", "\n", "Un des points évoqués dans les inconvénients du format CSV est la présence importante de données dupliquées. \n", "Cette notion est traitée dans les outils comme R et Pandas par la notion de catégories (`categoricals` pour pandas et `factor` pour R) qui permet d'associer une référence (un entier) à chaque donnée. \n", "\n", "La représentation d'une colonne peut alors se décomposer en une première liste de valeurs uniques et une deuxième liste des références à ces valeurs.\n", "\n", "L'exemple ci-dessous met en application cette représentation " ] }, { "cell_type": "code", "execution_count": 5, "id": "f693a8b7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['produit', ['banane', 'pomme', 'orange', 'piment'], [1, 1, 2, 2, 3, 3, 0, 0]]\n", "['produit', ['banane', 'orange', 'piment', 'pomme'], [3, 3, 1, 1, 2, 2, 0, 0]]\n" ] } ], "source": [ "liste = [\"pomme\", \"pomme\", \"orange\", \"orange\", \"piment\", \"piment\", \"banane\", \"banane\" ]\n", "name = \"produit\"\n", "\n", "# représentation avec des fonctions de base de python\n", "codec = list(set(liste))\n", "print([name, codec, [codec.index(val) for val in liste]])\n", "\n", "# représentation avec pandas\n", "import pandas as pd\n", "sr = pd.Series(liste, dtype = 'category', name=\"produit\")\n", "print([sr.name, list(sr.cat.categories), list(sr.cat.codes)])\n" ] }, { "cell_type": "markdown", "id": "acf0c432", "metadata": {}, "source": [ "Cette représentation semble d'un premier abord plus complexe puisqu'elle ne permet pas de reconstituer le séquencement des données dans une colonne et encore moins de visualiser l'ensemble des données d'une ligne. Par contre, elle permet très rapidement d'identifier la nature des données contenues dans le tableau sans nécessiter l'ouverture dans un tableur puis l'activation de filtres. \n", "\n", "Elle répond également au besoin exprimé de réduction du volume des données puisque la duplication de données disparait (remplacée par l'ajout de \"références\" de type entier peu volumineuses)." ] }, { "cell_type": "markdown", "id": "7da7842c", "metadata": {}, "source": [ "### Représentation optimisée\n", "La liste des références peut être optimisée en fonction des liens qui existent entre les différentes colonnes qui composent le tableau. \n", " \n", "Cette optimisation non détaillée ici (voir [l'article spécifique](https://nbviewer.org/github/loco-philippe/Environmental-Sensing/blob/main/documentation/FR_tabular_structure.ipynb) sur ce sujet) conduit soit à supprimer totalement cette liste, soit à la réduire.\n", "\n", "\n", "> *Rappel de l'exemple :*\n", ">\n", "|id|produit|aliment\t|quantité\t|prix|validité|disponibilité|\n", "|:------:|:------:|:------:|:------:|:------:|:------:|:------:|\n", "|11|pomme|fruit\t|sachet 1 kg\t|1\t|du 1/7/2022 au 31/12/2022|oui|\n", "|12|pomme|fruit\t|carton 10 kg\t|9|du 1/7/2022 au 31/12/2022|oui|\n", "|13|orange|fruit\t|sachet 1 kg|2|du 1/7/2022 au 31/12/2022|fin 2022|\n", "|14|orange|fruit\t|carton 10 kg\t|18\t|du 1/7/2022 au 31/12/2022|fin 2022|\n", "|15|piment|légume\t|sachet 1 kg\t|1.5|du 1/7/2022 au 31/12/2022|oui|\n", "|16|piment|légume\t|carton 10 kg|13|du 1/7/2022 au 31/12/2022|fin 2022|\n", "|17|banane|fruit\t|sachet 1 kg\t|0.5|du 1/7/2022 au 31/12/2022|oui|\n", "|18|banane|fruit\t|carton 10 kg\t|4|du 1/7/2022 au 31/12/2022|oui|\n", ">\n", "> *Les données ci-dessous représentent au format JSON les données de l'exemple dans une structure équivalente à celle d'un fichier csv :* \n", "> \n", ">```python\n", ">[['produit', ['piment', 'piment', 'banane', 'banane', 'pomme', 'pomme', 'orange', 'orange']],\n", "> ['quantite', ['sachet 1 kg', 'carton 10 kg', 'sachet 1 kg', 'carton 10 kg', 'sachet 1 kg', 'carton 10 kg', 'sachet 1 kg', 'carton 10 kg']],\n", "> ['aliment', ['legume', 'legume', 'fruit', 'fruit', 'fruit', 'fruit', 'fruit', 'fruit']],\n", "> ['validite', ['du 1/7/2022 au 31/12/2022', 'du 1/7/2022 au 31/12/2022', 'du 1/7/2022 au 31/12/2022', 'du 1/7/2022 au 12/2022', 'du 1/7/2022 au 31/12/2022', 'du 1/7/2022 au 31/12/2022', 'du 1/7/2022 au 31/12/2022', 'du 1/7/2022 au 31/12/2022']],\n", "> ['id', [15, 16, 17, 18, 11, 12, 13, 14]],\n", "> ['disponibilite', ['oui', 'fin 2022', 'oui', 'oui', 'oui', 'oui', 'fin 2022', 'fin 2022']],\n", "> ['prix', [1.5, 15, 0.5, 5, 1, 10, 2, 20]]]\n", ">```\n", "> \n", ">*Celles-ci représentent les mêmes données mais avec une représentation optimisée :* \n", ">```python\n", "> [['produit', ['piment', 'banane', 'pomme', 'orange']],\n", "> ['quantite', ['sachet 1 kg', 'carton 10 kg']],\n", "> ['aliment', ['fruit', 'legume'], [0, [1, 0, 0, 0]]],\n", "> ['validite', ['du 1/7/2022 au 31/12/2022']],\n", "> ['id', [15, 16, 17, 18, 11, 12, 13, 14]],\n", "> ['disponibilite', ['fin 2022', 'oui'], [4, [1, 0, 1, 1, 1, 1, 0, 0]]],\n", "> ['prix', [1.5, 15, 0.5, 5, 1, 10, 2, 20]]]\n", ">```\n", "> \n", ">*Ce format JSON peut également être partagé dans un format binaire (standard CBOR) avec un gain supplémentaire de volume de données.*\n", "> \n", " " ] }, { "cell_type": "markdown", "id": "a7482ca8", "metadata": {}, "source": [ "### Autres représentations\n", "Les représentations présentées ci-dessus minimisent la quantité de données incluses dans le format JSON. \n", "\n", "Les autres représentations ne sont pas détaillées car elles ajoutent des données de structure supplémentaires et conduisent à des tailles de fchiers bien souvent supérieures à celle d'un fichier CSV. \n", " \n", "A titre d'exemple, les autres modes de représentation proposés par pandas pour la liste 'produit' sont indiqués ci-dessous." ] }, { "cell_type": "code", "execution_count": 6, "id": "6ae3db64", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\"0\":\"pomme\",\"1\":\"pomme\",\"2\":\"orange\",\"3\":\"orange\",\"4\":\"piment\",\"5\":\"piment\",\"6\":\"banane\",\"7\":\"banane\"} \n", "\n", "{\"name\":\"produit\",\"index\":[0,1,2,3,4,5,6,7],\"data\":[\"pomme\",\"pomme\",\"orange\",\"orange\",\"piment\",\"piment\",\"banane\",\"banane\"]} \n", "\n", "[{\"produit\":\"pomme\",\"id\":15},{\"produit\":\"pomme\",\"id\":16},{\"produit\":\"orange\",\"id\":17},{\"produit\":\"orange\",\"id\":18},{\"produit\":\"piment\",\"id\":11},{\"produit\":\"piment\",\"id\":12},{\"produit\":\"banane\",\"id\":13},{\"produit\":\"banane\",\"id\":14}] \n", "\n", "{\"schema\":{\"fields\":[{\"name\":\"produit\",\"type\":\"string\"},{\"name\":\"id\",\"type\":\"integer\"}],\"pandas_version\":\"1.4.0\"},\"data\":[{\"produit\":\"pomme\",\"id\":15},{\"produit\":\"pomme\",\"id\":16},{\"produit\":\"orange\",\"id\":17},{\"produit\":\"orange\",\"id\":18},{\"produit\":\"piment\",\"id\":11},{\"produit\":\"piment\",\"id\":12},{\"produit\":\"banane\",\"id\":13},{\"produit\":\"banane\",\"id\":14}]}\n" ] } ], "source": [ "sr = pd.Series(liste, name=\"produit\")\n", "st = pd.Series([15, 16, 17, 18, 11, 12, 13, 14], name=\"id\")\n", "df = pd.DataFrame({'produit':sr, 'id':st})\n", "\n", "print(sr.to_json(orient='index'), '\\n')\n", "print(sr.to_json(orient='split'), '\\n')\n", "\n", "print(df.to_json(orient='records'), '\\n')\n", "print(df.to_json(orient='table', index=False))" ] }, { "cell_type": "markdown", "id": "e0454e56", "metadata": {}, "source": [ "## 6 - Synthèse\n", "\n", "### Volume de données\n", "\n", "Pour mesurer le gain d'un format alternatif au format CSV, deux exemples de fichiers opendata sont utilisés :\n", "- le fichier des mesures de qualité de l'air du 01/01/2022 : https://files.data.gouv.fr/lcsqa/concentrations-de-polluants-atmospheriques-reglementes/temps-reel/2022/ [(voir étude)](https://nbviewer.org/github/loco-philippe/Environmental-Sensing/blob/main/python/Validation/air/air.ipynb)\n", "- le fichier des bornes de recharge de véhicules électriques du 29/06/2022 : https://www.data.gouv.fr/fr/datasets/fichier-consolide-des-bornes-de-recharge-pour-vehicules-electriques/#resources [(voir étude)](https://nbviewer.org/github/loco-philippe/Environmental-Sensing/blob/main/python/Validation/irve/test_IRVE.ipynb)\n", "\n", "Le tableau ci-dessous présente le volume des données (en Ko) de ces deux fichiers avec les formats suivants :\n", "- formats textes :\n", " - CSV (non quoté)\n", " - JSON simple (données brutes)\n", " - JSON unique (utilisation de catégories)\n", " - JSON optimisé (avec réduction des références)\n", "- formats binaires :\n", " - CSV compressé\n", " - JSON optimisé (avec codage CBOR)\n", " - parquet (format de référence en terme de taille de fichier)\n", " \n", "|fichier |**CSV**|JSON simple|JSON unique|**JSON optimisé**||*CSV compressé*|*JSON optimisé CBOR*|*parquet*|\n", "|:------:|:------:|:------:|:------:|:------:||:------:|:------:|:------:|\n", "|air|**10 871**|14 971|4 048|**1 222**||*491*|*659*|*270*|\n", "|IRVE|**7 281**|9 455|3 614|**2 374**||*556*|*1 757*|*577*|\n", "\n", "*Nota : La taille 'JSON simple' est équivalente à celle d'un fichier CSV 'quoté' (non fourni dans ce tableau).*\n", " \n", "Ainsi, l'utilisation d'un format JSON permet d'obtenir un gain significatif par rapport à un format CSV. \n", "Le format JSON binaire permet d'obtenir un gain complémentaire mais le volume reste plus élevé qu'avec d'autres formats binaires. \n", "\n", "### Atteinte des objectifs \n", "\n", "Si l'on reprend la liste des critères d'évaluation définis, on peut compléter les résultats partiels présentés au chapitre 4 sur la base du format 'JSON optimisé':\n", "- simplicité : les entités manipulées sont limitées à 6 types d'objets et sont facilement compréhensibles.\n", "- disponibilité multi-plateformes : pour chaque langage, les objets JSON sont transposables et les codeurs/decodeurs JSON sont également disponibles.\n", "- format texte: oui.\n", "- interprétation aisée: la représentation choisie permet d'identifier rapidement les différentes valeurs utilisées pour chaque colonne.\n", "- niveau sémantique : limité à 6 types d'entités mais les types composés (object, array) permettent de représenter des objets complexes (ex. points (array) et polygones (array of array of array) définis par le format GeoJSON).\n", "- taille de fichier faible: Le passage à un format optimisé permet des gains significatifs.\n", "- réversibilité: oui (le typage explicite des colonnes permet la conversion inverse).\n", "- lisibilité de la structure des données: les noms des colonnes ainsi que le typage est explicite (si documenté)\n", "- usage fichier et API: oui, le format est identique entre une représentation fichier et un transfert via API. Ceci permet de banaliser la mise à disposition des données.\n", "- temps de réponse faible en lecture et écriture: non évalué (nécessite des outils opérationnels sur différents environnements)" ] }, { "cell_type": "markdown", "id": "0958ac82", "metadata": {}, "source": [ "## 7 - Conclusion\n", "\n", "Les conclusions du chapitre 4 peuvent maintenant être complétées :\n", "\n", "1. les structures tabulaires sont omniprésentes notamment dans le cadre open-data, un standard d'échange de ces structures est donc toujours indispensable,\n", "2. le format CSV n'est plus un format pérenne, on ne peut donc pas \"faire l'impasse\" d'une réflexion sur le choix d'un standard d'échange alternatif,\n", "3. le format JSON répond aux attentes d'un nouveau format d'échange des données tabulaires. \n", "4. son déploiement nécessite une phase préalable de choix du mode de représentation JSON retenu. \n", "\n", "Si l'on revient à la question initiale : *Quel avenir pour le format CSV ?*, deux réponses peuvent être données :\n", "\n", "Une première réponse factuelle serait : \n", "\n", ">Le format CSV présente des limitations fortes mais aucune solution alternative directement déployable n'est actuellement disponible. Ce format devra donc continuer à être utilisé dans l'attente d'un successeur.\n", "\n", "Une deuxième réponse plus engagée pourrait être : \n", "\n", ">Le format CSV présente des limitations fortes néanmoins des solutions alternatives existent et peuvent être mises en place. L'engagement de travaux sur ce sujet permettra de définir et déployer une solution satisfaisante.\n", "\n", "Mais c'est peut-être par une autre question que viendra la réponse :\n", "\n", ">Le déploiement des API en complément (et en alternative) au partage de fichier nécessite de standardiser les structures JSON portées par ces API. La structuration retenue pour ces API dans la cadre des données tabulaires deviendra alors une solution alternative au format CSV.\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" } }, "nbformat": 4, "nbformat_minor": 5 }