プログラミング練習記11日目_政府統計(e-stat)からデータをダウンロードする
今日も最初はプログラミング練習記から!
前回までは…
前回10日目「プログラミング練習記_10日目 データの取り込み」では、
e-statという政府統計サイトからデータをgoogle colaboratoryへ取り込むことが
思うようにできず、挫折したぽ話でした。
今日は雨がひどくて、作業できないなーということを理由に、
前回の失敗を雪辱してみました。
コツは”APP ID”と”statsCode”は別に用意する!でした。
再チャレンジ
今回も、
政府の統計データをe-Stat APIとPythonを使って取得する方法
と、公式ページのヘルプ「APIの使い方」
を参考にしてトライしてみました。
APIをgoogle colaboにとりこめてるんだけど、URLの指定が違うのかなー?
とあれこれ試してみて、
お目当ての統計の、APIダウンロードページの「URLコピー」をつかうのがうまくできました。
requestsライブラリを使って、url = でURLを指定します。
うまく動かなかった原因は、APP_IDをgetして貼り付けなかったこと。
やり方は参考サイトに詳しいです!
import requests
import pandas as pd
import json
url = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsData?appId=<YOUR_APP_ID>&lang=J&statsDataId=0003448233&metaGetFlg=Y&cntGetFlg=N&explanationGetFlg=Y&annotationGetFlg=Y§ionHeaderFlg=1&replaceSpChars=0"
# Replace <YOUR_APP_ID> with your actual app ID
resp = requests.get(url)
data = json.loads(resp.text)
data
この結果を表示すると、
{'GET_STATS_DATA': {'RESULT': {'STATUS': 0,
'ERROR_MSG': '正常に終了しました。',
'DATE': '2024-07-01T14:33:55.983+09:00'},
'PARAMETER': {'LANG': 'J',
'STATS_DATA_ID': '0003448233',
'DATA_FORMAT': 'J',
'START_POSITION': 1,
'METAGET_FLG': 'Y',
'EXPLANATION_GET_FLG': 'Y',
'ANNOTATION_GET_FLG': 'Y',
'REPLACE_SP_CHARS': 0,
'CNT_GET_FLG': 'N',
'SECTION_HEADER_FLG': 1},
'STATISTICAL_DATA': {'RESULT_INF': {'TOTAL_NUMBER': 336,
'FROM_NUMBER': 1,
'TO_NUMBER': 336},
'TABLE_INF': {'@id': '0003448233',
'STAT_NAME': {'@code': '00200524', '$': '人口推計'},
'GOV_ORG': {'@code': '00200', '$': '総務省'},
'STATISTICS_NAME': '人口推計 各年10月1日現在人口 令和2年国勢調査基準 統計表',
'TITLE': {'@no': '006', '$': '都道府県別人口の割合-総人口'},
'CYCLE': '年次',
'SURVEY_DATE': 0,
'OPEN_DATE': '2024-04-12',
'SMALL_AREA': 0,
'COLLECT_AREA': '該当なし',
'MAIN_CATEGORY': {'@code': '02', '$': '人口・世帯'},
'SUB_CATEGORY': {'@code': '01', '$': '人口'},
'OVERALL_TOTAL_NUMBER': 288,
'UPDATED_DATE': '2024-04-12',
'STATISTICS_NAME_SPEC': {'TABULATION_CATEGORY': '人口推計',
'TABULATION_SUB_CATEGORY1': '各年10月1日現在人口',
'TABULATION_SUB_CATEGORY2': '令和2年国勢調査基準',
'TABULATION_SUB_CATEGORY3': '統計表'},
'DESCRIPTION': '',
'TITLE_SPEC': {'TABLE_NAME': '都道府県別人口の割合-総人口'}},
'CLASS_INF': {'CLASS_OBJ': [{'@id': 'tab',
'@name': '表章項目',
'CLASS': {'@code': '003', '@name': '人口割合', '@level': '', '@unit': '%'}},
{'@id': 'area',
'@name': '全国・都道府県',
'CLASS': [{'@code': '00000', '@name': '全国', '@level': '1'},
{'@code': '01000', '@name': '北海道', '@level': '2'},
{'@code': '02000', '@name': '青森県', '@level': '2'},
{'@code': '03000', '@name': '岩手県', '@level': '2'},
{'@code': '04000', '@name': '宮城県', '@level': '2'},
{'@code': '05000', '@name': '秋田県', '@level': '2'},
{'@code': '06000', '@name': '山形県', '@level': '2'},
{'@code': '07000', '@name': '福島県', '@level': '2'},
{'@code': '08000', '@name': '茨城県', '@level': '2'},
{'@code': '09000', '@name': '栃木県', '@level': '2'},
…
となって、ようやく政府統計のサイトからweb経由でgoogle colaboへデータを取り込めました!!
このままではグラフにできないので、
参考サイトを参照しながらグラフにできるデータへと加工していきます。
まずはデータの値を取り出します。
values = data['GET_STATS_DATA']['STATISTICAL_DATA']['DATA_INF']['VALUE']
# JSONからDataFrameを作成
df = pd.DataFrame(values)
print(df)
結果を表示すると次の通り、
@tab @area @time @unit $
0 003 00000 2005000001 % 100.00
1 003 00000 2010000001 % 100.00
2 003 00000 2015000001 % 100.00
3 003 00000 2020000000 % 100.00
4 003 00000 2021000000 % 100.00
.. ... ... ... ... ...
331 003 47000 2015000001 % 1.13
332 003 47000 2020000000 % 1.16
333 003 47000 2021000000 % 1.17
334 003 47000 2022000000 % 1.18
335 003 47000 2023000000 % 1.18
…
これでは何を表しているのかわからないので、
値以外の情報を取り出します。
# メタ情報取得
meta_info = data['GET_STATS_DATA']['STATISTICAL_DATA']['CLASS_INF']['CLASS_OBJ']
# 統計データのカテゴリ要素をID(数字の羅列)から、意味のある名称に変更する
for class_obj in meta_info:
# メタ情報の「@id」の先頭に'@'を付与した文字列が、統計データの列名と対応している
column_name = '@' + class_obj['@id']
# 統計データの列名を「@code」から「@name」に置換するディクショナリを作成
id_to_name_dict = {}
if isinstance(class_obj['CLASS'], list):
for obj in class_obj['CLASS']:
id_to_name_dict[obj['@code']] = obj['@name']
else:
id_to_name_dict[class_obj['CLASS']['@code']] = class_obj['CLASS']['@name']
# ディクショナリを用いて、指定した列の要素を置換
df[column_name] = df[column_name].replace(id_to_name_dict)
print(df)
これを表示すると次のようになります。
@tab @area @time @unit $
0 人口割合 全国 2005年 % 100.00
1 人口割合 全国 2010年 % 100.00
2 人口割合 全国 2015年 % 100.00
3 人口割合 全国 2020年 % 100.00
4 人口割合 全国 2021年 % 100.00
.. ... ... ... ... ...
これでは表題部分がまだ使い慣れた日本語になっていないので、
次にこの部分を改良します。
# 統計データの列名を変換するためのディクショナリを作成
col_replace_dict = {'@unit': '単位', '$': '値'}
for class_obj in meta_info:
org_col = '@' + class_obj['@id']
new_col = class_obj['@name']
col_replace_dict[org_col] = new_col
# ディクショナリに従って、列名を置換する
new_columns = []
for col in df.columns:
if col in col_replace_dict:
new_columns.append(col_replace_dict[col])
else:
new_columns.append(col)
df.columns = new_columns
print(df)
これを実行すると、次のような見慣れた表データになります。
表章項目 全国・都道府県 時間軸(年) 単位 値
0 人口割合 全国 2005年 % 100.00
1 人口割合 全国 2010年 % 100.00
2 人口割合 全国 2015年 % 100.00
3 人口割合 全国 2020年 % 100.00
4 人口割合 全国 2021年 % 100.00
.. ... ... ... .. ...
331 人口割合 沖縄県 2015年 % 1.13
332 人口割合 沖縄県 2020年 % 1.16
333 人口割合 沖縄県 2021年 % 1.17
334 人口割合 沖縄県 2022年 % 1.18
335 人口割合 沖縄県 2023年 % 1.18
336 rows × 5 columns
ここまでは参考情報があったのでうまくできましたが、
これをグラフ化するのがまだまだ(。-`ω-)
ダウンロードしたデータが大きすぎて、
336列あるデータをグラフで可視化できませんでした。
グラフに使えるようにするためのデータの加工がまだうまくできてないですね。
なんとかグラフ化したのが次のグラフ。
グラフを見ると、東京と千葉の人口が多いのが視覚化されていますね。
とはいえ、いろいろ苦労してグラフ化しましたが、
現状では、政府統計(e-stat)のサイトから直接グラフ化した方が綺麗なグラフができています。
まだまだ修行がたりません(´・・`)
反省
ながながと書いてしまいましたが、
APIで政府統計のデータをダウンロードするのに気をつけるのはAPP IDをちゃんとつけること。
また、ダウンロードしたデータをよく読んで、
どういうコードでグラフ化したり表にしたりするのに必要なのか、
どんなデータを取り込むのかをはっきりさせていないといけないなとわかりました。
トライ&エラーあるのみですね。
practice makes perfect!
近況を少し…。
閑話休題、梅雨の末期ですね。
最後に最近の農作業の様子をば。
昨日の天気予報が気づくと変わっていて、
いつ晴れるのか、雨が降るのかわからずにモヤモヤする日々です。
また大雨が降って、川の堰が倒れてしまいそうです。
最近週2回の頻度で川の堰を立てている気がします。
時期的に不安定な気候が多いのですが、
災害につながるような雨や台風など起こりませんように…。
まとめ
プログラミング練習の記録です。
前回、政府統計サイトe-Statからデータを取り込むことに苦戦しましたが、今回は再挑戦。
APIのAPP IDとstatsCodeの設定がポイントでした。
URLの指定やライブラリの利用方法を工夫し、データの取り込みに成功。
データを整形してグラフ化する作業に進みましたが、まだまだ改良の余地あり。
一方、梅雨の末期で農作業が難しい日々。
雨続きで川の堰が倒れそうな状況が続いています。
災害につながるような雨や台風など起こりませんように…。