前回に引き続いて,公的データの取得に関してメモ。
Rだと便利なライブラリがあるが,Pythonだとやや面倒かも。
賃金構造基本統計調査 雇用形態別DBを例に説明していく
アプリケーションIDの用意
e-Statでユーザー登録し,アプリケーションIDを取得してコードに貼り付けておく
# 読み込み app_id = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
APIアクセス用メソッドの定義
共通する処理なのでメソッドにしておく
import pandas as pd import urllib import json # GETリクエストの送信からjson受け取り,dictへの変換までの流れを行うメソッド def get_estat_data(api_method: str, params: dict, api_version="3.0", return_format="json") -> dict: url = f"https://api.e-stat.go.jp/rest/{api_version}/app/{return_format}/{api_method}?{urllib.parse.urlencode(params)}" req = urllib.request.Request(url) with urllib.request.urlopen(req) as res: response = res.read() return json.loads(response.decode())
統計情報の取得
普通に人力で探す場合
- e-Stat: 政府統計の総合窓口で調べる
- 統計情報を探してstatsDataIdを取得するところまでは,人力のほうが早い場合が多い
APIのgetStatsListを使う場合
- APIで調べることもできる
- メソッドのURLは
getStatsList
- メソッドのURLは
全件取得する場合はパラメータにappIdのみを入れる
パラメータを設定することで,条件で絞り込んで取得できる
searchWord
に値を入れればキーワードで検索することもできる
params = { "appId": app_id, "searchWord": "賃金構造基本統計調査 雇用形態別" # キーワードで検索 } stats_list = get_estat_data(api_method="getStatsList", params=params) stats = stats_list["GET_STATS_LIST"]["DATALIST_INF"]["TABLE_INF"] stats_df = pd.io.json.json_normalize(stats) stats_df[["@id","STAT_NAME.$","STATISTICS_NAME","TITLE","CYCLE","SURVEY_DATE"]].head()
@idの「0003082750」が目的のstatsDataId
メタ情報の取得:getMetaInfo
- 一度に取得できるデータの上限は10万レコード
- 縦持ちテーブルでデータがDLされるので,この上限にはすぐに達してしまう
- リクエストパラメータで指定できるように,予め必要なデータ項目(変数,カラム)を調べておく必要がある
getMetaInfo
で調べられる
getMetaInfo
はstatsDataId
が必須パラメータなので,先程取得したIDを入れる
メタ情報の取得
stats_data_id = "0003082750" params = {"appId": app_id, "statsDataId": stats_data_id} meta_info = get_estat_data(api_method="getMetaInfo", params=params)
CLASS_INF:データに関する情報
class_info = meta_info["GET_META_INFO"]["METADATA_INF"]["CLASS_INF"]["CLASS_OBJ"] # 中身を見やすいように整形 tab = pd.io.json.json_normalize(class_info[0], record_path="CLASS") cat01 = pd.io.json.json_normalize(class_info[1], record_path="CLASS") cat02 = pd.io.json.json_normalize(class_info[2], record_path="CLASS") cat03 = pd.io.json.json_normalize(class_info[3], record_path="CLASS") cat04 = pd.io.json.json_normalize(class_info[4], record_path="CLASS") cat05 = pd.io.json.json_normalize(class_info[5], record_path="CLASS") cat06 = pd.io.json.json_normalize(class_info[6], record_path="CLASS") cat07 = pd.io.json.json_normalize(class_info[7], record_path="CLASS") cat08 = pd.io.json.json_normalize(class_info[8], record_path="CLASS")
これらの中身を見て,必要なデータを取得するためのコードを把握しておく。
統計データの取得:getStatsData
- 必要なカラムのidを指定してデータを取得する
- パラメータの詳細はこちら
params = { "appId": app_id, "statsDataId": stats_data_id, "cdTab": tab.loc[4, "@code"], "cdCat01": cat01.loc[0,"@code"], "cdCat02": cat02.loc[0,"@code"] } stats_data = get_estat_data(api_method="getStatsData", params=params)
DATA_INF:統計データ
# DATA_INF: 統計データ data_info = stats_data["GET_STATS_DATA"]["STATISTICAL_DATA"]["DATA_INF"]
ここにはNOTE
とVALUE
が入っている(data_info.keys()
で確認できる)
NOTE
は統計表上の欠損値の記号とその意味についての注釈文
# NOTE:欠損値の記号などについての注意書き data_info["NOTE"]
VALUE
は目的の統計データ
# VALUE: 統計データ data_df = pd.io.json.json_normalize(data_info, record_path="VALUE") data_df.head()
データは正規化されていて,例えば性別の「男性」が「01」というコードに変換されたような形で入っている。
CLASS_INFで取得したデータとJOINさせて整形していく必要がある(これが面倒…)