e-Stat APIからのデータ取得と活用
はじめに
e-Stat APIは、日本の政府統計総合窓口(e-Stat)が提供する公式統計データにプログラムからアクセスするための仕組みです。統計データを自動的に取得・活用したいデータサイエンティストやアプリケーション開発者にとって強力なツールとなります。
APIの種類と機能
1. 統計表情報取得API
統計表情報取得APIは、e-Statで提供されている統計表の情報を検索・取得するためのAPIです。
-
主な機能:
- 統計分野やキーワードによる統計表の検索
- 統計表ID、政府統計コード、調査年月などによる絞り込み
- 統計表の更新日付や公開状況の確認
- 統計調査の概要情報の取得
-
ユースケース:
- 利用可能な統計データの一覧取得
- 最新の統計表公開状況の確認
- 特定のテーマに関する統計表の検索
2. メタ情報取得API
メタ情報取得APIは、統計データの構造情報(メタデータ)を取得するためのAPIです。データの意味や構造を理解するために不可欠です。
-
主な機能:
- 統計データの項目定義情報の取得
- 分類項目や地域区分などのコード体系の取得
- データの階層構造に関する情報の取得
- 時系列データの時間軸情報の取得
-
ユースケース:
- データの意味を正確に理解するための項目定義確認
- 地域コードや産業分類コードなどの対応表取得
- データの集計レベルや粒度の確認
- 複雑な統計表の構造把握
3. 統計データ取得API
統計データ取得APIは、実際の統計数値データを取得するためのAPIで、最も頻繁に利用されるAPIです。
-
主な機能:
- 統計表の全データまたは条件指定による部分データの取得
- 地域・時間・項目による絞り込みデータの取得
- データのCSV/JSON/XML形式での出力
- 大規模データの分割取得(ページング機能)
-
ユースケース:
- 時系列分析のための経年データ取得
- 地域比較のための都道府県別データ取得
- 特定条件に絞ったデータの抽出
- 自動データ更新システムの構築
補足: その他のAPI機能
- データセット取得API: 複数の統計表を横断的に検索・取得
- 地域・時間コード取得API: 地域コードや時間軸のコード体系を取得
- 統計分類取得API: 産業分類や職業分類などの分類コード情報を取得
利用開始方法
1. アプリケーションIDの取得
APIを利用するには、まずアプリケーションIDを取得する必要があります:
- e-Statポータルサイトでユーザー登録
- 「API機能」→「アプリケーションIDの発行」から申請
- 審査後、IDが発行されます
2. メタ情報の取得
統計データを取得する前に、まずメタ情報を取得して統計表の構造を理解することが重要です。以下は、メタ情報取得APIを使用する例です:
import requests
import json
# API エンドポイントURL
url = "https://api.e-stat.go.jp/rest/3.0/app/json/getMetaInfo"
# パラメータの設定
params = {
"statsDataId": "0000010101", # 人口・世帯に関する統計表ID
"appId": "あなたのアプリケーションID"
}
# リクエストを送信
response = requests.get(url, params=params)
# 結果を表示
response_data = response.json()
# メタ情報から利用可能な項目を確認
if 'GET_META_INFO' in response_data and 'METADATA_INF' in response_data['GET_META_INFO']:
metadata = response_data['GET_META_INFO']['METADATA_INF']
# 統計表の基本情報
table_info = metadata['TABLE_INF']
print(f"統計表名: {table_info['STATISTICS_NAME']}")
print(f"表題: {table_info['TITLE']['$']}")
print(f"公開日: {table_info['OPEN_DATE']}")
# 分類項目の確認
if 'CLASS_INF' in metadata and 'CLASS_OBJ' in metadata['CLASS_INF']:
for class_obj in metadata['CLASS_INF']['CLASS_OBJ']:
print(f"\n分類: {class_obj['@name']}")
# 各分類の項目を表示
if 'CLASS' in class_obj:
classes = class_obj['CLASS']
if isinstance(classes, list):
for i, cls in enumerate(classes[:5]): # 最初の5項目のみ表示
print(f" - {cls['@name']} (コード: {cls['@code']})")
if len(classes) > 5:
print(f" ... 他 {len(classes)-5} 項目")
else:
print(f" - {classes['@name']} (コード: {classes['@code']})")
# JSONファイルに保存して後で詳細に分析
with open('estat_metadata.json', 'w', encoding='utf-8') as f:
json.dump(response_data, f, ensure_ascii=False, indent=4)
このコードを実行すると、統計表の構造や利用可能な分類項目(地域コード、時間コード、データ項目など)を確認できます。これにより、次のステップで実際のデータを取得する際に、必要な項目を正確に指定できるようになります。
2.1 カテゴリ情報の抽出と整理
メタ情報から特にカテゴリ情報(データの分類項目)を抽出して整理すると、データの構造をより理解しやすくなります。以下は、カテゴリ情報を抽出して整理するコードです:
# カテゴリ情報を格納する辞書
categories = {}
# APIレスポンスからカテゴリを抽出
meta_info = response_data
if "GET_META_INFO" in meta_info and "METADATA_INF" in meta_info["GET_META_INFO"]:
metadata_inf = meta_info["GET_META_INFO"]["METADATA_INF"]
# CLASS_INF(分類情報)
if "CLASS_INF" in metadata_inf:
class_inf = metadata_inf["CLASS_INF"]
class_obj_list = class_inf.get("CLASS_OBJ", [])
if not isinstance(class_obj_list, list):
class_obj_list = [class_obj_list]
# すべてのクラスオブジェクトを処理
for class_obj in class_obj_list:
class_name = class_obj.get("@name", "")
class_code = class_obj.get("@id", "") # @id を使用
# カテゴリに関連するクラスを探す(cat01, cat02など)
if class_code and class_code.startswith('cat'):
classes = class_obj.get("CLASS", [])
if not isinstance(classes, list):
classes = [classes]
category_items = {}
for cls in classes:
code = cls.get("@code", "")
name = cls.get("@name", "")
category_items[code] = name
categories[class_code] = {
'name': class_name,
'items': category_items
}
# カテゴリ一覧を表示
for cat_code, cat_info in categories.items():
print(f"\n【{cat_code}: {cat_info['name']}】")
for code, name in list(cat_info['items'].items())[:10]: # 最初の10項目のみ表示
print(f" {code}: {name}")
if len(cat_info['items']) > 10:
print(f" ... 他 {len(cat_info['items'])-10} 項目")
# カテゴリ情報をJSONファイルに保存
with open('estat_categories.json', 'w', encoding='utf-8') as f:
json.dump(categories, f, ensure_ascii=False, indent=4)
このコードを実行すると、統計表に含まれるカテゴリ(例:人口区分、年齢区分、地域区分など)とそれぞれの項目が整理されて表示され、JSONファイルとしても保存されます。これにより、データ取得時に必要なカテゴリコードを正確に指定できるようになります。
3. 基本的なデータ取得
メタ情報を理解したら、次は実際の統計データを取得します。以下は、人口データを取得して整形するための関数の例です:
import requests
import pandas as pd
import json
def get_population_data(app_id):
"""
e-Stat APIから人口データを取得する
引数:
app_id (str): e-Stat APIのアプリケーションID
戻り値:
pandas.DataFrame: フォーマットされた人口データ
"""
# APIのベースURL
api_url = "https://api.e-stat.go.jp/rest/3.0/app/json/getStatsData"
# リクエストパラメータ
params = {
"appId": app_id, # アプリケーションID
"statsDataId": "0000010101", # 人口統計ID
"cdCat01": "A1101" # 総人口のカテゴリコード
}
try:
# HTTPリクエストを実行
response = requests.get(api_url, params=params)
# リクエストが成功したか確認
response.raise_for_status()
# JSONレスポンスをパース
data = response.json()
# APIがエラーを返したか確認
result = data.get('GET_STATS_DATA', {}).get('RESULT', {})
if result.get('STATUS') != 0:
error_msg = result.get('ERROR_MSG', '不明なエラー')
raise Exception(f"APIがエラーを返しました: {error_msg}")
# 人口データを処理して返す
return process_population_data(data)
except requests.exceptions.RequestException as e:
print(f"リクエスト中にエラーが発生しました: {e}")
raise
except Exception as e:
print(f"データ処理中にエラーが発生しました: {e}")
raise
def process_population_data(data):
"""
人口データを処理してフォーマットする
引数:
data (dict): e-Stat APIからの生のJSONデータ
戻り値:
pandas.DataFrame: フォーマットされた人口データ
"""
# 統計データを抽出
statistical_data = data.get('GET_STATS_DATA', {}).get('STATISTICAL_DATA', {})
if not statistical_data:
raise Exception("レスポンスに統計データが見つかりません")
# メタデータと実際のデータ値を抽出
table_info = statistical_data.get('TABLE_INF', {})
class_info = statistical_data.get('CLASS_INF', {})
data_info = statistical_data.get('DATA_INF', {})
# 人口データの値を抽出
values = data_info.get('VALUE', [])
if not isinstance(values, list):
values = [values]
# DataFrameのためのリストを作成
records = []
for item in values:
area_code = item.get('@area')
time_code = item.get('@time')
value = float(item.get('$', 0))
records.append({
'area_code': area_code,
'area_name': get_area_name(area_code, class_info),
'time_code': time_code,
'time_period': get_time_name(time_code, class_info),
'population': value
})
# DataFrameを作成
df = pd.DataFrame(records)
# メタデータを属性として追加
df.attrs['title'] = table_info.get('STATISTICS_NAME', '人口データ')
df.attrs['source'] = table_info.get('STATISTICS_NAME', '')
df.attrs['updated'] = table_info.get('UPDATED_DATE', '')
return df
def get_area_name(area_code, class_info):
"""地域コードから地域名を取得する"""
class_objs = class_info.get('CLASS_OBJ', [])
if not isinstance(class_objs, list):
class_objs = [class_objs]
for obj in class_objs:
if obj.get('@id') == 'area':
classes = obj.get('CLASS', [])
if not isinstance(classes, list):
classes = [classes]
for cls in classes:
if cls.get('@code') == area_code:
return cls.get('@name', area_code)
return area_code
def get_time_name(time_code, class_info):
"""時間コードから時間期間名を取得する"""
class_objs = class_info.get('CLASS_OBJ', [])
if not isinstance(class_objs, list):
class_objs = [class_objs]
for obj in class_objs:
if obj.get('@id') == 'time':
classes = obj.get('CLASS', [])
if not isinstance(classes, list):
classes = [classes]
for cls in classes:
if cls.get('@code') == time_code:
return cls.get('@name', time_code)
return time_code
# 使用例
if __name__ == "__main__":
app_id = "あなたのアプリケーションID"
population_df = get_population_data(app_id)
# 結果を表示
print(f"取得したデータ: {len(population_df)}行")
print("\n最新の人口データ (上位5件):")
# 最新の年度のデータを抽出
latest_year = population_df['time_period'].max()
latest_data = population_df[population_df['time_period'] == latest_year].sort_values('population', ascending=False)
print(latest_data.head(5)[['area_name', 'time_period', 'population']])
# CSVファイルとして保存
population_df.to_csv('population_data.csv', index=False, encoding='utf-8')
print("\nデータをCSVファイルに保存しました: population_data.csv")
このコードは以下の処理を行います:
get_population_data()
関数:e-Stat APIから人口データを取得しますprocess_population_data()
関数:取得したデータを整形してDataFrameに変換しますget_area_name()
とget_time_name()
関数:コードから名称を取得します- 最後に、取得したデータの一部を表示し、CSVファイルとして保存します
このコードを実行すると、都道府県別の人口データが取得され、pandas DataFrameとして整形されます。これにより、データの分析や可視化が容易になります。
なお、APIリクエストでは以下のパラメータを指定しています:
statsDataId
: 統計表ID(この例では人口・世帯に関する統計表)cdCat01
: カテゴリコード(この例では総人口を指定)
これらのパラメータは、前のステップで取得したメタ情報から適切な値を選択しています。
データの分析と可視化
取得したデータは様々な形で活用できます:
import matplotlib.pyplot as plt
import japanize_matplotlib # 日本語フォント対応
# 取得したデータをDataFrameに変換する例
# (実際のレスポンス構造に合わせて調整が必要)
# グラフ作成例
plt.figure(figsize=(10, 6))
plt.bar(df['地域名'], df['人口数'])
plt.title('都道府県別人口')
plt.xlabel('都道府県')
plt.ylabel('人口(人)')
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('population.png')
plt.show()
実践的なユースケース
1. 時系列データの分析
複数年のデータを取得して経年変化を分析できます:
# 複数年の統計データを取得する例
years = range(2015, 2023)
data_by_year = {}
for year in years:
# APIパラメータを年ごとに変更
params["cdTime"] = str(year)
# データ取得処理
# ...
# 取得したデータを保存
data_by_year[year] = result_data
# 年ごとの変化をグラフ化
plt.figure(figsize=(12, 6))
for year, data in data_by_year.items():
plt.plot(data['区分'], data['値'], label=str(year))
plt.legend()
plt.title('年次推移')
plt.show()
2. 地域比較分析
地域ごとのデータを比較することも可能です:
# 都道府県コードを指定して地域別データを取得
prefecture_codes = ["01", "13", "27", "40"] # 北海道、東京、大阪、福岡
data_by_prefecture = {}
for code in prefecture_codes:
# APIパラメータを地域ごとに変更
params["cdArea"] = code
# データ取得処理
# ...
# 取得したデータを保存
data_by_prefecture[code] = result_data
# 地域間比較をグラフ化
# ...
注意点と制限事項
- APIの利用回数制限(標準アカウントで1日あたり50回まで)
- 大量データ取得時のページング処理の必要性
- データ形式(JSON/XML)の適切な指定
- 統計表IDの正確な把握
まとめ
e-Stat APIを活用することで、日本の豊富な統計データに簡単にアクセスでき、データ分析やアプリケーション開発に役立てることができます。公式ドキュメントをしっかり確認し、必要なデータを効率的に取得・活用できるようになりましょう。