1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

e-stat APIで政府統計データ(都道府県&性&年代別)取得(json) -> 値とカテゴリマスタからDataFrame生成

Last updated at Posted at 2020-04-04

この記事を読む前に

基本的なこと(e-stat APIの利用方法 〜 Pandasのデータフレームへの変換)はこちらの記事に詳しく書かれています
【Python3】e-StatのAPIで遊んでみる「サービス業が増えている?」

この記事のポイント

下記を実施したコード(Python3)を共有します
■ e-statAPIにより、都道府県別ごとの性年代別(5歳刻み)の人口データを使用
■ jsonに含まれるマスタを適用して、数値コードを意味ある文字列に変換する処理を実施(これがちょっとめんどくさかった)

結果として、こんな感じのデータフレームを使えるようになります
image.png

コード共有

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)  # 結合していく

こんな感じのデータになります。
image.png
属性がコードになってるので解釈は無理ですね。これから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])

これでこんな感じの解釈できるデータになります。
image.png
以上!

コードの説明が少なくて申し訳ないですが、とりあえず動くとは思うので興味ある方お試しください〜。
(別のデータだと形式が全く同じではないので、途中でコケる可能性があります。)
(マスタのあたり、もっとすっきり書けないかな〜と思ってます。アドバイスあれば是非お願いします。)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?