この記事を読む前に
基本的なこと(e-stat APIの利用方法 〜 Pandasのデータフレームへの変換)はこちらの記事に詳しく書かれています
【Python3】e-StatのAPIで遊んでみる「サービス業が増えている?」
この記事のポイント
下記を実施したコード(Python3)を共有します
■ e-statAPIにより、都道府県別ごとの性年代別(5歳刻み)の人口データを使用
■ jsonに含まれるマスタを適用して、数値コードを意味ある文字列に変換する処理を実施(これがちょっとめんどくさかった)
結果として、こんな感じのデータフレームを使えるようになります
コード共有
e-stat APIを使ってjsonデータを取得するまで
結果は「json_data」という変数に格納されます。
# リクエストURL生成
import urllib
url_base = 'http://api.e-stat.go.jp/rest/3.0/app/json/getStatsData?'
params = {
'appId':【取得したアプリケーションID】,
'lang':'J',
'statsDataId':'0003312321',
'metaGetFlg':'Y',
'cntGetFlg':'N',
'sectionHeaderFlg':'1',
}
url = url_base + urllib.parse.urlencode(params, safe=',')
# リクエスト&json取得
import json
req = urllib.request.Request(url)
with urllib.request.urlopen(req) as res:
json_data = json.load(res)
※アプリケーションIDは自分が取得したものに変えてくださいね
数値データ部分をデータフレームに変換
結果は「df_merged」という変数に格納
import pandas as pd
value_list = (json_data
['GET_STATS_DATA']
['STATISTICAL_DATA']
['DATA_INF']
['VALUE'])
df_merged = pd.DataFrame() # 空のデータフレームを用意。追加していく
for dct in value_list:
df_tmp = pd.io.json.json_normalize(dct) # 辞書をデータフレームへ変換
df_merged = pd.concat([df_merged, df_tmp], axis=0) # 結合していく
こんな感じのデータになります。
属性がコードになってるので解釈は無理ですね。これからjsonのマスタ部分を使って変換します
マスタの適用
# マスタ部分を扱い易い形に変換
class_obj_list = (json_data
['GET_STATS_DATA']
['STATISTICAL_DATA']
['CLASS_INF']
['CLASS_OBJ']
)
class_obj_dct = {} # 空の辞書を用意
for dct_class_obj in class_obj_list:
dct_tmp = {}
# 辞書の場合と、複数の辞書のリストになっている場合がある
if isinstance(dct_class_obj['CLASS'], dict): # 辞書の場合
code = dct_class_obj['CLASS']['@code'] # ex. 01000
name = dct_class_obj['CLASS']['@name'] # ex. 北海道
dct_tmp[code] = name
elif isinstance(dct_class_obj['CLASS'], list): # リストの場合
for i in range(len(dct_class_obj['CLASS'])): # リストの中身は辞書
code = dct_class_obj['CLASS'][i]['@code'] # なるべく上と似た書き方が出来るようにした
name = dct_class_obj['CLASS'][i]['@name']
dct_tmp[code] = name
else: raise('想定外動作') # 想定外なのでエラーで止まるようにしておく
class_obj_dct[dct_class_obj['@id']] = dct_tmp # 辞書を追加
# マスタの適用
for key, dct in class_obj_dct.items():
col = '@' + key # ex. @area
df_merged[col] = df_merged[col].apply(lambda s: dct[s])
コードの説明が少なくて申し訳ないですが、とりあえず動くとは思うので興味ある方お試しください〜。
(別のデータだと形式が全く同じではないので、途中でコケる可能性があります。)
(マスタのあたり、もっとすっきり書けないかな〜と思ってます。アドバイスあれば是非お願いします。)