Travailler avec des JSON imbriqués

Ingestion de données rationalisée avec pandas

Amany Mahfouz

Instructor

JSON imbriqués

  • Les JSON contiennent des objets avec des paires attribut-valeur
  • Un JSON est imbriqué quand la valeur est elle-même un objet
Ingestion de données rationalisée avec pandas

Exemple de réponse JSON tirée de la documentation Yelp Business API

Ingestion de données rationalisée avec pandas

Exemple de données Yelp, avec coordonnées et emplacement imbriqués mis en évidence

Ingestion de données rationalisée avec pandas

Exemple de données Yelp, avec les catégories imbriquées mises en évidence

Ingestion de données rationalisée avec pandas

Exemple de données Yelp, mettant en évidence les enregistrements imbriqués sous businesses

Ingestion de données rationalisée avec pandas
# Afficher les colonnes contenant des données imbriquées
print(bookstores[["categories", "coordinates", "location"]].head(3))
                                          categories  \
0   [{'alias': 'bookstores', 'title': 'Bookstores'}]   
1  [{'alias': 'bookstores', 'title': 'Bookstores'...   
2   [{'alias': 'bookstores', 'title': 'Bookstores'}]     

                                         coordinates  \
0  {'latitude': 37.7975997924805, 'longitude': -1...   
1  {'latitude': 37.7885846793652, 'longitude': -1...   
2  {'latitude': 37.7589836120605, 'longitude': -1...    

                                            location  
0  {'address1': '261 Columbus Ave', 'address2': '...  
1  {'address1': '50 2nd St', 'address2': '', 'add...  
2  {'address1': '866 Valencia St', 'address2': ''...
Ingestion de données rationalisée avec pandas

pandas.io.json

  • Le sous-module pandas.io.json offre des outils pour lire et écrire des JSON
    • Nécessite sa propre instruction import
  • json_normalize()
    • Accepte un dictionnaire ou une liste de dictionnaires (comme pd.DataFrame())
    • Retourne un dataframe aplati
    • Modèle par défaut pour les noms de colonnes aplaties : attribute.nestedattribute
    • Choisissez un autre séparateur avec l'argument sep
Ingestion de données rationalisée avec pandas

Charger des données JSON imbriquées

import pandas as pd
import requests

from pandas.io.json import json_normalize
# Configurer les en-têtes, les paramètres et le point de terminaison de l'API api_url = "https://api.yelp.com/v3/businesses/search" headers = {"Authorization": "Bearer {}".format(api_key)} params = {"term": "bookstore", "location": "San Francisco"}
# Appeler l'API et extraire les données JSON response = requests.get(api_url, headers=headers, params=params) data = response.json()
Ingestion de données rationalisée avec pandas
# Aplatir les données et charger dans un dataframe, avec des séparateurs _
bookstores = json_normalize(data["businesses"], sep="_")
print(list(bookstores))
['alias', 
 'categories',
 'coordinates_latitude',
 'coordinates_longitude',
 ...
 'location_address1',
 'location_address2',
 'location_address3',
 'location_city',
 'location_country',
 'location_display_address',
 'location_state',
 'location_zip_code',
 ...
 'url']
Ingestion de données rationalisée avec pandas

Données fortement imbriquées

print(bookstores.categories.head())
0     [{'alias': 'bookstores', 'title': 'Bookstores'}]
1    [{'alias': 'bookstores', 'title': 'Bookstores'...
2     [{'alias': 'bookstores', 'title': 'Bookstores'}]
3     [{'alias': 'bookstores', 'title': 'Bookstores'}]
4    [{'alias': 'bookstores', 'title': 'Bookstores'...
Name: categories, dtype: object
Ingestion de données rationalisée avec pandas

Données fortement imbriquées

  • json_normalize()
    • record_path : chaîne/liste d'attributs pointant vers les données imbriquées
    • meta : liste d'autres attributs à charger dans le dataframe
    • meta_prefix : chaîne à préfixer aux noms de colonnes meta
Ingestion de données rationalisée avec pandas

Données fortement imbriquées

# Aplatir les catégories et ajouter les détails d'entreprise
df = json_normalize(data["businesses"],
                    sep="_",

record_path="categories",
meta=["name", "alias", "rating", ["coordinates", "latitude"], ["coordinates", "longitude"]],
meta_prefix="biz_")
Ingestion de données rationalisée avec pandas
print(df.head(4))
        alias               title                biz_name  \
0  bookstores          Bookstores   City Lights Bookstore   
1  bookstores          Bookstores  Alexander Book Company   
2  stationery  Cards & Stationery  Alexander Book Company   
3  bookstores          Bookstores       Borderlands Books   

                              biz_alias  biz_rating  biz_coordinates_latitude  \
0   city-lights-bookstore-san-francisco         4.5                 37.797600   
1  alexander-book-company-san-francisco         4.5                 37.788585   
2  alexander-book-company-san-francisco         4.5                 37.788585   
3       borderlands-books-san-francisco         5.0                 37.758984   

   biz_coordinates_longitude  
0                -122.406578  
1                -122.400631  
2                -122.400631  
3                -122.421638
Ingestion de données rationalisée avec pandas

Passons à la pratique !

Ingestion de données rationalisée avec pandas

Preparing Video For Download...