盆暗の学習記録

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

pythonによるe-stat APIからのデータ取得

前回に引き続いて,公的データの取得に関してメモ。

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())

統計情報の取得

普通に人力で探す場合

APIのgetStatsListを使う場合

  • APIで調べることもできる
    • メソッドのURLはgetStatsList
  • 全件取得する場合はパラメータに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

f:id:nigimitama:20190810165015p:plain

メタ情報の取得:getMetaInfo

  • 一度に取得できるデータの上限は10万レコード
  • 縦持ちテーブルでデータがDLされるので,この上限にはすぐに達してしまう
    • リクエストパラメータで指定できるように,予め必要なデータ項目(変数,カラム)を調べておく必要がある
    • getMetaInfoで調べられる
  • getMetaInfostatsDataIdが必須パラメータなので,先程取得した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")

f:id:nigimitama:20190810165736p:plain

f:id:nigimitama:20190810170015p:plain

これらの中身を見て,必要なデータを取得するためのコードを把握しておく。

統計データの取得:getStatsData

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"]

ここにはNOTEVALUEが入っている(data_info.keys()で確認できる)

f:id:nigimitama:20190810173732p:plain

NOTEは統計表上の欠損値の記号とその意味についての注釈文

# NOTE:欠損値の記号などについての注意書き
data_info["NOTE"]

f:id:nigimitama:20190810173812p:plain

VALUEは目的の統計データ

# VALUE: 統計データ
data_df = pd.io.json.json_normalize(data_info, record_path="VALUE")
data_df.head()

f:id:nigimitama:20190810174118p:plain

データは正規化されていて,例えば性別の「男性」が「01」というコードに変換されたような形で入っている。

CLASS_INFで取得したデータとJOINさせて整形していく必要がある(これが面倒…)