盆暗の学習記録

データサイエンス ,エンジニアリング,ビジネスについて日々学んだことの備忘録としていく予定です。初心者であり独学なので内容には誤りが含まれる可能性が大いにあります。

pythonによるRESAS APIからのデータ取得

今までRでしか取得したことがなく,Pythonでは初めてだったのでメモ

使い方の流れ

  1. 利用登録してAPIキーを取得
  2. RESAS-API - API概要を見て,取得するデータを決める
  3. 取得したいデータのURLにGETリクエストを送れば(アクセスすれば)JSON形式でデータを取得できる
    • urllibライブラリのurllib.request.Request()メソッドで取得できる
    • パラメータ(?cityCode=11362みたいなやつ)を付加する場合はurllib.parse.urlencode()を使う
  4. 取得したJSONデータを整形する
    • jsonライブラリのjson.loads()pythonの辞書型に変換
    • pandaspd.io.json.json_normalize()などで辞書型をDataFrame型に変換

コードの例

RESASデータ取得用の関数

import urllib
import pandas as pd
import json
api_key = {"X-API-KEY": "ここに取得したAPIキーを入力"}


def get_resas_data(params: dict, api_path: str, api_key: dict) -> dict:
    api_endpoint = "https://opendata.resas-portal.go.jp/"
    url = api_endpoint + api_path
    url = (url + "?" + urllib.parse.urlencode(params)) if (params != None) else url
    req = urllib.request.Request(url, headers = api_key)
    with urllib.request.urlopen(req) as res:
        response = res.read()
    resas_data_dict = json.loads(response.decode())
    return resas_data_dict

例:都道府県一覧の取得

# 都道府県一覧の取得
resas_data = get_resas_data(params=None, api_path="api/v1/prefectures", api_key=api_key)
prefectures = pd.io.json.json_normalize(resas_data['result'])

f:id:nigimitama:20190804205207p:plain

例:市区町村一覧の取得

cities = pd.DataFrame()
for i in range(1,48):
    resas_data = get_resas_data(params={"prefCode": i}, api_path="api/v1/cities", api_key=api_key)
    cities_i = pd.io.json.json_normalize(resas_data['result'])
    cities = pd.concat([cities, cities_i], axis=0)

f:id:nigimitama:20190804205142p:plain

例:出生数・死亡数/転入数・転出数の取得

都道府県や市区町村とは異なり,こういうデータは返ってくるJSONがネスト(入れ子)していて整形が面倒。

pd.io.json.json_normalize()やpandasの前処理関数(例えばpd.DataFrame.pivot())を駆使して整形していく。

例えば,次のように,リストと文字列が入っている辞書型データは,pd.io.json.json_normalize()できれいにデータフレームに変換できる

# 辞書の入ったリストと文字列を含む辞書型データ
data_dict = {'data': [{'value': 34780, 'year': 1995},
                        {'value': 36035, 'year': 2000},
                        {'value': 46769, 'year': 2005}],
                        'label': '総人口'}
# record_pathにリストのキーを指定,metaにそれ以外のキーを指定
pd.io.json.json_normalize(data_dict, record_path="data", meta=["label"])

f:id:nigimitama:20190804204500p:plain

データの取得

といった知識をもとに書いたコードがこれ

api_path = "api/v1/population/sum/estimate"
params={"prefCode": 13, "cityCode": 13101}
resas_data = get_resas_data(params=params, api_path=api_path, api_key=api_key)
data_list = resas_data["result"]["data"]
for i in range(len(data_list)):
    resas_df_i = pd.io.json.json_normalize(data_list[i], record_path="data", meta=["label"])
    resas_df_i = resas_df_i.pivot(index="year", columns="label", values="value").reset_index()
    resas_df = resas_df_i if i == 0 else pd.merge(resas_df, resas_df_i, on="year")

f:id:nigimitama:20190804204844p:plain