🗾

公的統計APIからデータ取得するPythonのライブラリを作りました

2022/10/15に公開約8,100字

はじめに

公的統計APIからデータ取得するPythonのライブラリを作りました。サンプルnotebookをGitHubにアップしています。
PyCon JP 2022で「Pythonで公的統計APIのオープンデータ活用」というタイトルで発表しました。発表資料はこちら

公的統計APIについて

公的統計とは、国の行政機関・地方公共団体などが作成する統計のことです。統計法で定義されています。
日本の公的統計は、e-Stat 政府統計の総合窓口で見ることができます。

e-Stat 政府統計の総合窓口

e-Statは、日本の統計が閲覧できる政府統計ポータルサイトです。
総務省統計局が管理しており、CSVなどでデータをダウンロードできます。利用の際は、e-Statの利用規約をご確認ください。

e-Statには、政府統計の総合窓口(e-Stat)で提供している統計データを機械判読可能な形式で取得できるAPI機能があります。テーブル数で20万件程度のデータセットが提供されています。利用の際は、e-Stat API機能の利用規約をご確認ください。

e-Stat API機能のアプリケーションID発行

e-Stat API機能使うには、アプリケーションID発行が必要です。以下の流れで利用できます。

  1. 利用ガイドに従って、
  2. 利用規約を確認し、
  3. ユーザー登録して、
  4. アプリケーションIDの取得
    • 「マイページ」→「API機能(アプリケーションID発行)」から、必須入力項目を埋めて発行
  5. API仕様を見ながら、開発!
  6. クレジット表示を忘れずに

クレジット表示(e-Statのページから引用)

クレジット表示を忘れないようにしましょう。

API機能を使用したサービスを公開される場合には、下記のクレジット表示をお願いします。

「このサービスは、政府統計総合窓口(e-Stat)のAPI機能を使用していますが、サービスの内容は国によって保証されたものではありません。」

利用される方が参照できる場所であれば、表示場所の指定はございません

API利用時は、サーバーへの思いやりを大切に

e-Stat API機能利用規約に禁止事項が記載されています。

第8条(禁止事項)
1.利用者は、以下に掲げる行為を行ってはならないものとします。
(1) 本機能の運用を妨害する行為
(2) 短時間における大量のアクセスその他本機能の運用に支障を与える行為
2.統計センターは、上記に該当する行為を行っている場合又は該当する行為を行うおそれがあると判断した場合、利用者に対して、本機能の利用を停止することができるものとします。

Pythonのライブラリを作りました

インストール

pipでインストールできます。

pip install jpy-datareader

クイック・スタート

import jpy_datareader.data as web

api_key = "Your_Application_ID"
df = web.DataReader("0003109558", "estat", api_key=api_key)

JPy-DataReaderの使い方

e-Stat API機能の事前準備

e-Stat API機能に事前にユーザー登録して、アプリケーションIDをを取得します。

api_key = "Your_Application_ID" # 取得したアプリケーションID 

e-Stat API機能でのデータ取得

tatsDataIdは「統計表情報取得」で得られる統計表IDです。e-Statのデータベースから検索できます。「政府統計コード」ではなく、「統計表表示 ID」です。

requestsでのデータ取得

まず、JPy-DataReaderを使わず、requestsでデータ取得してみます。

pip install requests
import requests

url = "https://api.e-stat.go.jp/rest/3.0/app/json/getStatsData?"
params = {
    "appId": api_key,
    "statsDataId": "0003000795",
}

res = requests.get(url, params)
out = res.json()

out
{'GET_STATS_DATA': {'RESULT': {'STATUS': 0,
   'ERROR_MSG': '正常に終了しました。',
   'DATE': '2022-10-02T16:44:52.002+09:00'},
  'PARAMETER': {'LANG': 'J',
   'STATS_DATA_ID': '0003000795',
   'DATA_FORMAT': 'J',
   'START_POSITION': 1,
   'METAGET_FLG': 'Y'},
  'STATISTICAL_DATA': {'RESULT_INF': {'TOTAL_NUMBER': 343578,
    'FROM_NUMBER': 1,
    'TO_NUMBER': 100000,
    'NEXT_KEY': 100001},
   'TABLE_INF': {'@id': '0003000795',
    'STAT_NAME': {'@code': '00200561', '$': '家計調査'},
    'GOV_ORG': {'@code': '00200', '$': '総務省'},
    'STATISTICS_NAME': '家計調査 家計収支編 単身世帯',
    'TITLE': {'@no': '002', '$': '用途分類 用途分類(年齢階級別)'},
    'CYCLE': '四半期',
    'SURVEY_DATE': 0,
    'OPEN_DATE': '2022-08-05',

JSONの中身を見てみます。

確認

out.keys()

出力

dict_keys(['GET_STATS_DATA'])

確認

out['GET_STATS_DATA'].keys()

出力

dict_keys(['RESULT', 'PARAMETER', 'STATISTICAL_DATA'])

確認

out['GET_STATS_DATA']['STATISTICAL_DATA'].keys()

出力

dict_keys(['RESULT_INF', 'TABLE_INF', 'CLASS_INF', 'DATA_INF'])

確認

out['GET_STATS_DATA']['STATISTICAL_DATA'][ 'DATA_INF'].keys()

出力

dict_keys(['NOTE', 'VALUE'])

統計データ自体は以下に格納されています。

out['GET_STATS_DATA']['STATISTICAL_DATA'][ 'DATA_INF']['VALUE']

出力

[{'@tab': '01',
  '@cat01': '001',
  '@cat02': '21',
  '@cat03': 'A00',
  '@cat04': '0',
  '@area': '00000',
  '@time': '2000000103',
  '@unit': '一万分比',
  '$': '10000'},
 {'@tab': '01',
  '@cat01': '001',
  '@cat02': '21',
  '@cat03': 'A00',
  '@cat04': '0',
  '@area': '00000',
  '@time': '2000000406',
  '@unit': '一万分比',
  '$': '10000'},
 {'@tab': '01',

pandasのデータフレーム形式で読み込みます。

pip install pandas
import pandas as pd

df = pd.DataFrame(out['GET_STATS_DATA']['STATISTICAL_DATA'][ 'DATA_INF']['VALUE'])
df

VALUEだけでは、それぞれの列が何を表しているのかわかりません。各列のメタデータはCLASS_INFに格納されており、列ID名で結合することができます。

out['GET_STATS_DATA']['STATISTICAL_DATA']['CLASS_INF']['CLASS_OBJ']
[{'@id': 'tab',
  '@name': '表章項目',
  'CLASS': {'@code': '01', '@name': '金額', '@level': ''}},
 {'@id': 'cat01',
  '@name': '用途分類',
  '@description': '「事業・内職収入」は「事業・内職収入(農林漁業収入を除く)(~2019 年)」、「事業・内職収入(農林漁業収入を含む)(2020 年~)」に分割しています。',
  'CLASS': [{'@code': '001',
    '@name': '世帯数分布(抽出率調整)',
    '@level': '1',
    '@unit': '一万分比'},
   {'@code': '002', '@name': '集計世帯数', '@level': '1', '@unit': '世帯'},
   {'@code': '009', '@name': '世帯主の年齢', '@level': '1', '@unit': '歳'},
   {'@code': '010', '@name': '有業者比率', '@level': '1', '@unit': '%'},
   {'@code': '011', '@name': '持家率', '@level': '1', '@unit': '%'},
   {'@code': '015', '@name': '家賃・地代を支払っている世帯の割合', '@level': '1', '@unit': '%'},
   {'@code': '018', '@name': '受取', '@level': '1', '@unit': '円'},
   {'@code': '019',
    '@name': '実収入',
pd.DataFrame(out['GET_STATS_DATA']['STATISTICAL_DATA']['CLASS_INF']['CLASS_OBJ'][1][ 'CLASS'])

値の列「$」を見ると、数値でない欠損と思われる特殊文字があります。

sorted(df['$'].unique().tolist())
['-',
 '0',
 '0.0',
 '0.08',
 '0.09',
 '0.10',
 '0.11',

特殊文字はNOTEで、どのような種類があるかとその意味を調べることができます。

out['GET_STATS_DATA']['STATISTICAL_DATA'][ 'DATA_INF']['NOTE']
[{'@char': '***', '$': '調査又は集計していないもの'},
 {'@char': '-', '$': '該当数字がないもの'},
 {'@char': 'X', '$': '数値が秘匿されているもの'}]

JPy-DataReaderでデータ取得

e-Statなど公的統計APIからデータを取得するPythonのライブラリJPy-DataReaderを作りました。

pip install jpy-datareader

さくっとデータ取得する場合、以下の2行でデータ取得とデータ加工ができます。

import jpy_datareader as jdr

df = jdr.get_data_estat_statsdata(api_key, statsDataId="0003000795")
df

以下も同じ挙動です。

import jpy_datareader.data as web

df = web.DataReader("0003000795", "estat", api_key=api_key)
df

よくデータ取得に使われるpandas-datareaderに仕様を似せています。

pip install pandas-datareader
import pandas_datareader as pdr
pdr.get_data_fred('GS10').tail(10)  # 10年満期米国債市場金利

import pandas_datareader.data as web
web.DataReader('TUD', 'oecd')  # 労働組合データ

from pandas_datareader import fred
fred.FredReader('GS10').read()

もう少し細かく設定してデータ取得したい場合には、以下を使います。

from jpy_datareader import estat

statsdata = estat.StatsDataReader(api_key, statsDataId="0003000795")
df = statsdata.read()

免責事項・クレジット

  • 本記事に記載された情報は執筆者にて判断した情報源を元に個人が作成したものであり、所属組織が作成したものではありません。
  • 本記事に記載された内容は、資料作成時点においてのものであり、予告なく変更する場合があります。
  • 本記事の内容および情報の正確性、完全性等について、何ら保証を行っておらず、また、いかなる責任を持つものではありません。
  • 本記事は、政府統計総合窓口(e-Stat)のAPI機能で取得したデータを使用していますが、資料の内容(数値)は国によって保証されたものではありません。

おまけ

Discussion

ログインするとコメントできます