e-StatのAPIから統計データを取得しPandas DataFrameに変換する

動作確認にはGoogleColaboratoryを利用しています。

e-Stat（政府統計の総合窓口）は日本の統計が閲覧できる政府統計ポータルサイトです。

本記事では下記の流れでPythonを利用したe-Stat APIの利用方法についてご説明します
1. ユーザ登録とアプリケーションIDの取得（事前準備）
2. e-StatのサイトからリクエストURLをコピー
3. PythonからAPIを利用してXML形式でデータを取得し, DataFrame形式に加工

# ユーザ登録とアプリケーションIDの取得
e-StatのAPIの利用にはe-Statのユーザ登録とアプリケーションIDが必要です。
手順はe-Stat APIの利用ガイドに記載があります。5分程度で完了し, すぐに使えるようになります。

https://www.e-stat.go.jp/api/api-info/api-guide

![スクリーンショット 2021-03-13 15.43.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201765/efbd4962-bb56-c265-bd3a-9965d42c69d4.png)

# リクエストURLの取得
リクエストに必要なURLを取得します。

### 前提知識
s-StatではAPIの機能として以下の７つが提供されています。今回はその中で<b>統計データ取得</b>を利用します。詳細な仕様は[API 仕様 3.0版](https://www.e-stat.go.jp/api/api-info/e-stat-manual3-0)を参照してください。

* 統計表情報取得
* メタ情報取得
* <b>統計データ取得
* データセット登録
* データセット参照
* データカタログ情報取得
* 統計データ一括取得

### e-StatからのリクエストURL取得方法
API（3.0版）の場合XMLで統計データを取得する際のURLの形式は以下です。
http(s)://api.e-stat.go.jp/rest/3.0/app/getStatsData?<パラメータ群>

この時に必須となるパラメータが下表の通りです。

| パラメータ名 | 意味                          |
|:-----------|-----------------------------:|
|appId       |取得済のアプリケーションID        |
|statsDataId |「統計表情報取得」で得られる統計表ID|


表にある「統計表ID」は「統計表情報取得」のAPIを利用して取得することもできますが, 今回はe-Statのサイトから直接コピーしてくる方法を紹介します。分析する統計はサイトで確認しながら選びたいという方におすすめです。

e-Stat APIのページからAPIで提供されるデータの一覧ページにリンクします。

https://www.e-stat.go.jp/api/api-info/api-data

政府統計一覧ページに飛ぶため、キーワード検索などにより利用したい政府統計を特定し, 政府統計名の部分を押下します。さらに詳細な条件の選択画面が表示されるため利用したい条件を選択していきます。
![スクリーンショット 2021-03-13 16.23.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201765/6fda2768-1505-7103-2bcf-de595633d50c.png)

今回の例では以下の順で選択しています。
社会人口統計体系 > 都道府県データ > 基礎データ-年度次

![スクリーンショット 2021-03-13 16.33.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201765/014d85e8-3c7f-cd54-5a99-a2af5250a553.png)

最終的に上図のように表示・ダウンロードという項目に「API」というボタンが表示されるため, それをクリックすると統計表IDが入った状態のリクエストIDが表示されるのでそれをコピーして自分のアプリケーションIDを追記すれば使用できるようになります。

![スクリーンショット 2021-03-13 16.39.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201765/bbd4d50c-3fc3-b9d0-db35-7ce3da791a89.png)

画像中のURLをコピペするとこのようになっています。

http\://api.e-stat.go.jp/rest/3.0/app/getStatsData?appId=&lang=J&statsDataId=0000010101&metaGetFlg=Y&cntGetFlg=N&explanationGetFlg=Y&annotationGetFlg=Y&sectionHeaderFlg=1

メタ情報の取得フラグなど必須でないものも含まれているため[API 仕様 3.0版](https://www.e-stat.go.jp/api/api-info/e-stat-manual3-0)を参照しながら必要なパラメータを使用するようにしてください。

# 今回作成したコード
PythonからAPIを利用してXML形式でデータを取得し, DataFrame形式に加工していきます。

```python
import requests
import defusedxml.ElementTree as ET
import pandas as pd

def get_estat_data(url):
  r = requests.get(url)
  tree = ET.fromstring(r.text)

  dict_array = []
  for i in tree.iter(tag='VALUE'):
    tmp_array = i.attrib
    tmp_array['val'] = i.text
    dict_array.append(tmp_array)

  result_df = pd.DataFrame(dict_array)
  for i in tree.iter(tag='CLASS_OBJ'):
    code_l = []
    name_l = []
    level_l = []
    unit_l = []
    for s in i.findall('CLASS'):
      code_l.append(s.attrib['code'])
      name_l.append(s.attrib['name'])
    tmp_df = pd.DataFrame({i.attrib['id']:code_l, i.attrib['name']:name_l}) 

    result_df = pd.merge(result_df, tmp_df, on=i.attrib['id'])

  return result_df

# メイン
appid = "取得済のアプリケーションID"
url = "http://api.e-stat.go.jp/rest/3.0/app/getStatsData?appId={}&lang=J&statsDataId=0000010101".format(appid)
df = get_estat_data(url)

```

結果図のようなデータフレーム形式のデータに加工できました。（先頭５行を表示）
![スクリーンショット 2021-03-21 20.25.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201765/aa7f1458-541f-6a0d-9eaf-2d131d1d7828.png)

# コード中のタグの解説
[API 仕様 3.0版](https://www.e-stat.go.jp/api/api-info/e-stat-manual3-0)の4.4「統計データ取得」にXMLで出力されるデータ形式について説明があります。
タグにどのような情報が含まれるか把握しておくとデータ取得時の理解が深まります。

### VALUE
>統計数値(セル)の情報です。データ件数分だけ出力されます。
属性として表章事項コード(tab)、分類事項コード(cat01 ～ cat15)、地域事項コード(area)、時間軸事項コード(time)、単位(unit)、注釈記号(anotation)を保持します。全ての属性はデータがある場合のみ出力されます。

/GET_STATS_DATA/STATISTICAL_DATA/ の階層にあります。
結果例の図でいうと英字の列の部分にあたります。
統計数値の情報が含まれており, 属性の情報も含まれますがコード値のためこのままだと意味を理解できません。


### CLASS_OBJ
>メタ情報の数分だけ出力します。属性としてメタ情報のID(id)、名称(name)及び解説(description)を保持します。解説はデータがある場合のみ出力されます。

/GET_STATS_DATA/STATISTICAL_DATA/CLASS_INF の階層にあります。
結果の図でいうとコード値部分の列名を和名に紐づけるのに利用しています。

### CLASS
>メタ情報を構成する要素の数分だけ出力します。属性としてメタ情報要素のコード(code)、名称(name)、階層レベル(level)、単位(unit)、親コード(parentCode)及び追加情報(addInf)を保持します。単位、親コード及び追加情報はデータがある場合のみ出力されます。指定した絞り込み条件又はデータセットの条件又はその両方の条件によって抽出されるメタ情報のみ出力されます。

/GET_STATS_DATA/STATISTICAL_DATA/CLASS_INF の階層にあります。
各コード値と対応する和名のデータを保持しています。

# その他注意事項
統計データ取得で１度に取得できるデータは執筆現在最大10万件です。
属性値の種類が多い統計の場合簡単に10万件を超えるので注意してください。

>Q7 : 【統計データ取得機能】10万件を超えるデータを取得できません。
A7 : API機能は、一度に最大で10万件のデータを返却します。そのため、統計データが一度に取得できない場合には、継続データの取得開始位置をレスポンスの<NEXT_KEY>タグの値として出力します。継続データを要求する場合は、データ取得開始位置パラメータ(startPosition)にこの値を指定することで、取得できます。