L’exploitation des données ouvertes est souvent tributaire du modèle des données publiées. Il arrive souvent que les données soient publiées dans un format spécifique difficilement exploitable car présentant des informations qui relèveraient d’une représentation hiérarchique mais qui par commodité sont livrées sans réelle organisation.
Cet article vise à montrer comment il est possible en utilisant la librairie Python/pandas de mettre à plat les données opendata sous la forme d’une table unique.
import pandas as pnd
Le premier exemple est tiré du site France Très Haut Débit. Il propose un fichier au format Excel avec par commune : les couvertures par technologie (DSL, câble et fibre) et par débit (éligible, 3, 8, 30 et 100 Mbits/s). Au total, le fichier présente 23 colonnes.
Le principe de mise à plat consiste à :
df = pnd.read_excel("FranceTHD_Open_Data_Observatoire_Juin2015.xlsx",\
sheetname="Communes",\
header=1)
df.head()
new_index = list(df.columns.values[0:3])
df.set_index(new_index, inplace=True)
df.head()
df.columns = [["Tout"] * 5 + ["DSL"] * 5 + ["Câble"] * 5 + ["Fibre"] * 5,\
["1 Mbit", "3 Mbit", "8 Mbit", "30 Mbit", "100 Mbit"] * 4]
df.columns.names = ["Techno", "Débit"]
df.head()
Après mise à plat, les données peuvent être représentées sous la forme d’une table à 6 colonnes seulement : département, code INSEE, commune, technologie, débit et valeur, bien plus facile à exploiter.
# noms des colonnes hiérarchiques
current_columns = df.columns.names
# noms des colonnes de la table finale
new_columns = df.index.names + current_columns + ["Value"]
# empilement des colonnes hiérarchiques vers l'index puis annulation de l'index
df = df.stack(current_columns).reset_index()
df.columns = new_columns
df.head()
Le second exemple, toujours dans le domaine des télécoms, est tiré du site OpenDataSoft. Il propose un fichier CSV avec par commune : les couvertures en population et surfacique par opérateur (Orange, Bouygues, SFR et Free) et par technologie (2G, 3G et 4G). Au total, le fichier présente 37 colonnes.
df = pnd.read_csv("couverture-2g-3g-4g-en-france-par-operateur-juillet-2015.csv",\
sep=";")
df.head()
new_index = list(df.columns.values[0:6]) + [df.columns.values[-1]]
df.set_index(new_index, inplace=True)
df.head()
df.columns = [["Population"] * 15 + ["Surfacique"] * 15,\
(["4G"] * 5 + ["3G"] * 5 + ["2G"] * 5) * 2,\
["Orange", "Bouygues", "SFR", "Free", "Any"] * 6]
df.columns.names = ["Type", "Techno", "Opérateur"]
df.head()
A nouveau, après mise à plat, les données peuvent être représentées sous la forme d’une table à 11 colonnes seulement : codes postal et INSEE, commune, département, surface, population, coordonnées, type, technologie, opérateur et valeur.
# noms des colonnes hiérarchiques
current_columns = df.columns.names
# noms des colonnes de la table finale
new_columns = df.index.names + current_columns + ["Value"]
# empilement des colonnes hiérarchiques vers l'index puis annulation de l'index
df = df.stack(current_columns).reset_index()
df.columns = new_columns
df.head()
N.B. : la séparation de la latitude et de la longitude de la colonne « coordonnées » n’est pas traitée dans cet exemple.
Copyright © 2016 Yotta Conseil