- はじめに
- APIを利用する前の事前知識
- 早速データを取得する
- API Requestの結果確認
- データ個数などの確認
- とりあえずメタ情報色々表示させてみます
- APIのクラスを確認する
- 最後にデータ取得
はじめに
機械学習プロジェクトにて政府統計の総合窓口、e-Stat APIを経由してデータを取得しようと考えている。
特に今回は国政調査のデータを取得して、データセットのカラムを増やしたいと考えている。
とは言ってもちゃんとまずは取得してみないことにはどんなものなのか掴めないので今回はとにかく触るのが目的である。
そのため、matplotlibとかSeabornとかおしゃれな可視化ライブラリを用いてデータを可視化するようなことはしない。
(そういうおしゃれイケメンなことを今後はしたい願望はある)
「とにかく触わる」これが最大の目的である。
(あわよくば苦手意識をなくす)
APIを利用する前の事前知識
API Keyの取得については小僧が説明せずとも素晴らしい記事が他に存在するのでその記事を紹介させていただくだけとする。
早速データを取得する
とりあえず、モジュール類をインストールする
# モジュールのインポート import pandas as pd import numpy as np import urllib import urllib.request import requests import json
API keyの値をセットする
# API KEYの設定 appId = "Your API Key"
データの取得は下記の通り小僧は書いてみた。
- APIのバージョンは 最新の3.0を利用。
#JSONデータの取得 def get_json(base_url, params): params_str = urllib.parse.urlencode(params) ## URLをエンコードする url = base_url + params_str ## リクエストパラメータを作成 json = requests.get(url).json() ## 指定のURLにリクエストを送る return json def main(): base_url = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsData?" statsDataId="0003152960" ## 統計票ID searchKind=2 ## 検索するデータの種別を指定する limit=2 #所得件数 #パラメータセット params = { "appId" : appId, "statsDataId" : statsDataId, ## これは指定が必須 "limit" : limit, "searchKind": searchKind } json=get_json(base_url, params) return json res = main()
上記でデータの取得結果はres
に格納された状態となりました。
ちょっと思ったのはRubyの場合はメソッド内で明示的にreturn
しなくてもいいけどPythonは明示的に書かないと呼び出し元に値が戻らないんだなぁ〜って。
初めての言語がRubyだったからそういう言語もあるのかって。
(ていうか、明示的に書くのが全体的にみてスタンダードですかね?)
API Requestの結果確認
APIリクエストの結果は下記で確認できる。
これに以上がある場合は何かしらエラーがある場合だ。
print(res["GET_STATS_DATA"]["RESULT"]["ERROR_MSG"])
データ個数などの確認
またまたデータの値ではなくメタ情報ですが、下記のようにデータの総数や本リクエストで取得したデータが何番目〜何番目のものなのかなどを確認することもできます。
data_total = res["GET_STATS_DATA"]["STATISTICAL_DATA"]["RESULT_INF"]["TOTAL_NUMBER"] data_from = res["GET_STATS_DATA"]["STATISTICAL_DATA"]["RESULT_INF"]["FROM_NUMBER"] data_to = res["GET_STATS_DATA"]["STATISTICAL_DATA"]["RESULT_INF"]["TO_NUMBER"] print("データ総数は{}個でした。\n今回は{}~{}個までのデータを取得しています。".format(data_total, data_from, data_to))
とりあえずメタ情報色々表示させてみます
table_info = res["GET_STATS_DATA"]["STATISTICAL_DATA"]["TABLE_INF"] id = table_info["@id"] stat_name = table_info["STAT_NAME"]["$"] stat_id = table_info["STAT_NAME"]["@code"] gov_name = table_info["GOV_ORG"]["$"] gov_id = table_info["GOV_ORG"]["@code"] statistical_name = table_info["STATISTICS_NAME"] statistical_title = table_info["TITLE"]["$"] statistical_id = table_info["TITLE"]["@no"] print("■ 統計調査名は\x1b[34m「{}」\x1b[mです。IDは\x1b[34m「{}」\x1b[mです。\n".format(stat_name, stat_id)) print("■ \x1b[34m「{}」\x1b[mによる調査です。IDは\x1b[34m「{}」\x1b[mです。\n".format(gov_name, gov_id)) print("■ この調査表の名前は\x1b[34m「{}」\x1b[mです。\n".format(statistical_name)) print("■ 調査タイトル名は\x1b[34m「{}」\x1b[mです。\n".format(statistical_title))
APIのクラスを確認する
クラスの確認はこちらで
class_data=res["GET_STATS_DATA"]["STATISTICAL_DATA"]["CLASS_INF"]["CLASS_OBJ"]
クラスオブジェクトに関しては下図をみていただいた方が良いと思う。
図のように{ '@id' : 'tab'
…}のような構造でそれぞれの統計データをソートできるようになっている。
この@idに対応するtabや今回統計表IDだとcat01
とかの属性値を確認してみる
下はtab
のデータの説明で、要は6、7、795でソートできるということ。
6 = 一般世帯数
7 = 一般世帯人員
795 = 1世帯あたりの人員
なので例えば、一般世帯数のデータのみを抽出しようとするならtagの値を6とすれば良い。
このことは表章事項と読んでいるみたいで、取得した後でわざわざソートをせずとも、APIリクエストの段階でそーとしたデータを取得することも可能なようだ。
class_data=res["GET_STATS_DATA"]["STATISTICAL_DATA"]["CLASS_INF"]["CLASS_OBJ"] df_tab = pd.DataFrame(class_data[0]["CLASS"]) df_tab
それぞれのデータにおいても同様に抽出して、それぞれのデータの表す意味を確認することができる。
class_obj_cat01 = class_data[1]["@name"] class_obj_cat01_id = class_data[1]["@id"] print("\n表章項目は「{}」で表章IDは{}です".format(class_obj_cat01, class_obj_cat01_id)) df_cat01 = pd.DataFrame(class_data[1]["CLASS"]) df_cat01
これ、今回は表章項目と表章IDと言っていますが、正しくは項目コードかもしれないので要注意。
最後にデータ取得
これまではひたすらにメタデータを取得してきましたが、ここで初めて値を取得しようと思います。
df_data = pd.DataFrame.from_dict(res["GET_STATS_DATA"]["STATISTICAL_DATA"]["DATA_INF"]["VALUE"]) df_data.head()
値はこれで取得できます。
すごくわかりずらいが、今回は全体で8052件のデータがあるのだが一つのレスポンスに同系統の3種類のデータが入っていることになっている。
なぜならtab:表章項目?を指定していないから。
今一度記載するが、下記のデータが入っていて
6 = 一般世帯数
7 = 一般世帯人員
795 = 1世帯あたりの人員
これらがそれぞれ2684件ずつ、合計8052件入っている。
なんともややこしい、、、
これ、統計表IDを指定したら、メタデータを確認して目的のデータを取得するように間違いなくパラメータを変えてデータを取得した方が良い。
だって処理めんどくさいし。
これらを頑張って、DataFrameで結合しまくった処理もありますが見苦しいので今回はここまでにしておきます。