處理巢狀 JSON

使用 pandas 的精實資料導入

Amany Mahfouz

Instructor

巢狀 JSON

  • JSON 由屬性—值配對的物件組成
  • 當值本身是物件時,JSON 就是巢狀的
使用 pandas 的精實資料導入

來自 Yelp Business API 文件的範例 JSON 回應

使用 pandas 的精實資料導入

Yelp 回應資料範例,標示出巢狀的座標與位置資料

使用 pandas 的精實資料導入

Yelp 回應資料範例,標示出巢狀的分類資料

使用 pandas 的精實資料導入

Yelp 回應資料範例,標示 businesses 下的巢狀紀錄

使用 pandas 的精實資料導入
# Print columns containing nested data
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': ''...
使用 pandas 的精實資料導入

pandas.io.json

  • pandas.io.json 子模組提供讀寫 JSON 的工具
    • 需要各自的 import 陳述式
  • json_normalize()
    • 接受字典/字典清單(類似 pd.DataFrame()
    • 回傳攤平的 dataframe
    • 預設欄名樣式:attribute.nestedattribute
    • sep 參數指定不同分隔符
使用 pandas 的精實資料導入

載入巢狀 JSON 資料

import pandas as pd
import requests

from pandas.io.json import json_normalize
# Set up headers, parameters, and API endpoint api_url = "https://api.yelp.com/v3/businesses/search" headers = {"Authorization": "Bearer {}".format(api_key)} params = {"term": "bookstore", "location": "San Francisco"}
# Make the API call and extract the JSON data response = requests.get(api_url, headers=headers, params=params) data = response.json()
使用 pandas 的精實資料導入
# Flatten data and load to dataframe, with _ separators
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']
使用 pandas 的精實資料導入

更深層巢狀資料

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
使用 pandas 的精實資料導入

更深層巢狀資料

  • json_normalize()
    • record_path:巢狀資料的屬性字串/字串清單
    • meta:一併載入到 dataframe 的其他屬性清單
    • meta_prefix:加在 meta 欄名的字首字串
使用 pandas 的精實資料導入

更深層巢狀資料

# Flatten categories data, bring in business details
df = json_normalize(data["businesses"],
                    sep="_",

record_path="categories",
meta=["name", "alias", "rating", ["coordinates", "latitude"], ["coordinates", "longitude"]],
meta_prefix="biz_")
使用 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
使用 pandas 的精實資料導入

一起來練習吧!

使用 pandas 的精實資料導入

Preparing Video For Download...