Backup

概要

内容

このnoteでは、統計局が提供している国勢調査のメッシュ統計の取得方法について解説いたします。

メッシュ統計とは、地域を隙間なく網の目(メッシュ)の区域に分けたものです。

こんな感じ、この各枠内の推定値を取得したいって話ですね。

で今回は、これの、1km版を取得して行こうと思ういます。

さっきのを区画をより、小さくした感じ。

縦1km✖️横1kmの正方形内の推定値を取得して1919810な感じ。


対象者

pythonという言語を少々扱うため、

・学校でpythonをやったことある

・progateでpythonやったことある

という方を対象に進めて行きます。

やったことある方は、やりますねぇ☝️

また、少々小中学校の算数が出てくるのでそこだけちょっと難しいかも。

けど、高校レベルの数学を使わないことを約束します。(そもそも、自分ができないので)


アカウント作成

まずは、政府統計の総合窓口でデータを取得するためのアカウントを発効しましょう。

emailを登録したら、すぐにメールが届くのでリンクを踏んで本登録する。

 そしたら、アカウント作成完了が表示されるので右上の緑色のログインボタンでログインする。

ログインができたらAPI機能(アプリケーションID発行)にとんで、アカウントを発行してください。

取得できなかった方は、これ使ってください

8f3722a4fd1c48f94be0f02cfbb30baf7e9d3d17


取得内容

実際に、メッシュ統計で取得できるデータセットはこちらになっています。

国勢調査や経済センサスなどいろいろありますが、今回は国勢調査の項目をを取得したいと思います。

国勢調査で取得できる内容を見てみると、

こんな感じで今回は、

その3の学生数、就業者数を取得したいと思います。

以上の2つの項目を1kmメッシュ単位で取得するには、

統計表と統計データを用い取得することができます。

詳しくは、こちらに記載されています。(仕様)


手順としては、

統計表で、

・データセットの種類(国勢調査、経済センサス etc .. )の選択

・1キロ平方メートルメッシュの選択

・項目(その1、その2、その3)の選択

・1次メッシュのidの取得

統計データで、

統計表で選択した1次メッシュのidから、3次メッシュ(1kmメッシュ単位)の推定値を取得します。


取得実行

そしたら、実際にAPIを叩いていきます。

それでは、まず統計表の取得からです

import urllib
import urllib.request
import json
import pprint

appId = "8f3722a4fd1c48f94be0f02cfbb30baf7e9d3d17"


#-------------StatsListの取得-------------

#url
url = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsList?"

#パラメーター
keys = {
       "appId"            : appId,
       "lang"             : "J" ,
       "statsCode"        : "00200521",
       "surveyYears"      : "201510",
       "searchKind"       : "2"
}
#urlの生成 ex. appId=8f3722a4fd1c48f94be0f02cfbb30baf7e9d3d17&lang=J&searchKind=2&statsCode=00200521&surveyYears=201510
paramStr = urllib.parse.urlencode(keys)

#urlの生成 ex. http://api.e-stat.go.jp/rest/3.0/app/json/getStatsList?appId=8f3722a4fd1c48f94be0f02cfbb30baf7e9d3d17&lang=J&searchKind=2&statsCode=00200521&surveyYears=201510
rObj   = urllib.request.urlopen(url + paramStr)

#Jsonを読み込む
resStr = rObj.read()

#Jsonをdecode
res = json.loads(resStr)

#objectを表示
pprint.pprint(res)

こちらに、codeを用意しました。

環境の問題を避けたい方は、google colabを使ってcodeを走らせてください。

パラメータは、

"statsCode" : "00200521" 国勢調査

"surveyYears" : "201510" データ取得日程2015年

"searchKind" : "2" メッシュ統計

で、平成27年度版のメッシュ統計のデータセットに絞っています。


そうすると以下のようなデータがたくさん返ってきましたね。

{
    '@id': '8003001658',
    'CYCLE': '-',
    'DESCRIPTION': '',
    'GOV_ORG': {'$': '総務省',
           '@code': '00200'},
    'MAIN_CATEGORY': {'$': '人口・世帯',
                 '@code': '02'},
    'OPEN_DATE': '2019-10-08',
    'OVERALL_TOTAL_NUMBER': 58317,
    'SMALL_AREA': 0,
    'STATISTICS_NAME': '平成27年国勢調査 '
                  '世界測地系(250Mメッシュ)',
    'STATISTICS_NAME_SPEC': {'TABULATION_CATEGORY': '平成27年国勢調査',
                        'TABULATION_SUB_CATEGORY1': '世界測地系(250Mメッシュ)'},
    'STAT_NAME': {'$': '国勢調査',
             '@code': '00200521'},
    'SUB_CATEGORY': {'$': '人口',
                '@code': '01'},
    'SURVEY_DATE': 201510,
    'TITLE': {'$': 'その3\u3000'
              '従業地・通学地集計及び世帯構造等基本集計に関する事項 '
              '1次メッシュ '
              'M5539',
         '@no': '5539'},
    'TITLE_SPEC': {'TABLE_NAME': 'その3\u3000'
                            '従業地・通学地集計及び世帯構造等基本集計に関する事項',
              'TABLE_SUB_CATEGORY1': '1次メッシュ',
              'TABLE_SUB_CATEGORY2': 'M5539'},
    'UPDATED_DATE': '2019-10-08'
 }

この中で僕たちは、STATISTICS_NAME_SPECのTABULATION_SUB_CATEGORY1が

'世界測地系(1KMメッシュ)'

というものを選びたいです。


また、先ほど取得内容で確認したTITLE_SPECのTABLE_NAMEが

・'その3\u3000従業地・通学地集計及び世帯構造等基本集計に関する事項'

であるものを選びたいです。


この条件で、これらの@idを取得しましょう。

import urllib
import urllib.request
import json
import pprint

appId = "8f3722a4fd1c48f94be0f02cfbb30baf7e9d3d17"
statsDataIds = []

#-------------StatsListの取得-------------

#url
url = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsList?"

#パラメーター
keys = {
       "appId"            : appId,
       "lang"             : "J" ,
       "statsCode"        : "00200521",
       "surveyYears"      : "201510",
       "searchKind"       : "2"
}
#urlの生成 ex. appId=8f3722a4fd1c48f94be0f02cfbb30baf7e9d3d17&lang=J&searchKind=2&statsCode=00200521&surveyYears=201510
paramStr = urllib.parse.urlencode(keys)

#urlの生成 ex. http://api.e-stat.go.jp/rest/3.0/app/json/getStatsList?appId=8f3722a4fd1c48f94be0f02cfbb30baf7e9d3d17&lang=J&searchKind=2&statsCode=00200521&surveyYears=201510
rObj   = urllib.request.urlopen(url + paramStr)

#Jsonを読み込む
resStr = rObj.read()

#Jsonをdecode
res = json.loads(resStr)


dataset = res["GET_STATS_LIST"]["DATALIST_INF"]["TABLE_INF"]

#条件をつけて内包表記でループ処理
[statsDataIds.append(data["@id"]) for data in dataset if data["STATISTICS_NAME_SPEC"]["TABULATION_SUB_CATEGORY1"] == "世界測地系(1KMメッシュ)" and data["TITLE_SPEC"]["TABLE_NAME"] == "その3\u3000従業地・通学地集計及び世帯構造等基本集計に関する事項"]


pprint.pprint(statsDataIds)

codeはこちら

idが取得できました。

['8003000692',
'8003000735',
'8003000622',
'8003000616',
'8003000726',
'8003000623',
'8003000712',
'8003000600',
'8003000686',
'8003000736',
'8003000617',
'8003000713',
'8003000704',
'8003000737',
'8003000652',
'8003000643',
'8003000694',
'8003000614',
'8003000599',
'8003000703',
'8003000663',
'8003000664',
'8003000615',
'8003000642',
'8003000693',
'8003000591',
'8003000714',
'8003000624',
'8003000715',
'8003000601',
'8003000602',
'8003000687',
'8003000610',
'8003000644',
'8003000716',
'8003000727',
'8003000632',
'8003000603',
'8003000728',
'8003000634',
'8003000729',
'8003000635',
'8003000730',
'8003000705',
'8003000688',
'8003000654',
'8003000605',
'8003000717',
'8003000675',
'8003000653',
'8003000592',
'8003000645',
'8003000676',
'8003000633',
'8003000665',
'8003000604',
'8003000718',
'8003000707',
'8003000646',
'8003000678',
'8003000739',
'8003000677',
'8003000731',
'8003000636',
'8003000706',
'8003000738',
'8003000655',
'8003000689',
'8003000657',
'8003000647',
'8003000658',
'8003000732',
'8003000656',
'8003000680',
'8003000625',
'8003000679',
'8003000695',
'8003000611',
'8003000593',
'8003000618',
'8003000720',
'8003000637',
'8003000594',
'8003000626',
'8003000595',
'8003000681',
'8003000696',
'8003000612',
'8003000719',
'8003000698',
'8003000740',
'8003000682',
'8003000699',
'8003000639',
'8003000638',
'8003000723',
'8003000606',
'8003000648',
'8003000627',
'8003000619',
'8003000666',
'8003000628',
'8003000697',
'8003000722',
'8003000721',
'8003000710',
'8003000672',
'8003000683',
'8003000651',
'8003000641',
'8003000701',
'8003000668',
'8003000690',
'8003000669',
'8003000667',
'8003000640',
'8003000596',
'8003000725',
'8003000620',
'8003000709',
'8003000608',
'8003000671',
'8003000621',
'8003000724',
'8003000708',
'8003000649',
'8003000700',
'8003000670',
'8003000650',
'8003000607',
'8003000597',
'8003000711',
'8003000691',
'8003000662',
'8003000684',
'8003000685',
'8003000631',
'8003000598',
'8003000630',
'8003000741',
'8003000613',
'8003000659',
'8003000702',
'8003000673',
'8003000609',
'8003000674',
'8003000733',
'8003000629',
'8003000660',
'8003000734',
'8003000661']

この選定したidを元に、統計データから1kmの推定値を取得することができます。

それでは、試しにこのidの統計データを引っ張ってみましょう。(上からテキトーに一個idを選んでー)

import urllib
import urllib.request
import json
import pprint

appId = "8f3722a4fd1c48f94be0f02cfbb30baf7e9d3d17"

url = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsData?"
keys = {
       "appId"            : appId,
       "lang"             : "J" ,
       "statsDataId"      : "8003000692" #ここに先ほど取得したidをいれる
}

paramStr = urllib.parse.urlencode(keys)
rObj   = urllib.request.urlopen(url + paramStr)
resStr = rObj.read()
res = json.loads(resStr) 
pprint.pprint(res)

codeはこちら

すると以下のようなCLASS_INFとDATA_INFが返ってきましたね。

'CLASS_INF': {'CLASS_OBJ': [{'@id': 'cat01',
         '@name': '経済構成別一般世帯数及び従業地・通学地別',
         'CLASS': [{'@code': '0010',
                    '@level': '1',
                    '@name': '\u3000'
                             '農林漁業就業者世帯の一般世帯数',
                    '@unit': '世帯'},
                   {'@code': '0020',
                    '@level': '1',
                    '@name': '\u3000'
                             '農林漁業・非農林漁業就業者混合世帯の一般世帯数',
                    '@unit': '世帯'},
                   {'@code': '0030',
                    '@level': '1',
                    '@name': '\u3000'
                             '非農林漁業就業者世帯の一般世帯数',
                    '@unit': '世帯'},
                   {'@code': '0040',
                    '@level': '1',
                    '@name': '\u3000'
                             '非就業者世帯の一般世帯数',
                    '@unit': '世帯'},
                   {'@code': '0050',
                    '@level': '1',
                    '@name': '\u3000'
                             '当地に常住する15歳以上就業者・通学者\u3000'
                             '総数',
                    '@unit': '人'},
                   {'@code': '0060',
                    '@level': '2',
                    '@name': '\u3000'
                             '当地に常住する15歳以上就業者・通学者\u3000'
                             '就業者数',
                    '@parentCode': '0050',
                    '@unit': '人'},
                   {'@code': '0070',
                    '@level': '2',
                    '@name': '\u3000'
                             '当地に常住する15歳以上就業者・通学者\u3000'
                             '通学者数',
                    '@parentCode': '0050',
                    '@unit': '人'}]},
        {'@id': 'cat02',
         '@name': '秘匿地域・合算地域有り',
         'CLASS': [{'@code': '1',
                    '@level': '1',
                    '@name': '無し'},
                   {'@code': '2',
                    '@level': '1',
                    '@name': '合算'},
                   {'@code': '3',
                    '@level': '1',
                    '@name': '秘匿'}]},
        {'@id': 'area',
         '@name': 'M3622',
         'CLASS': [{'@code': '36225727',
                    '@level': '1',
                    '@name': '36225727'},
                   {'@code': '36225728',
                    '@level': '1',
                    '@name': '36225728'},
                   {'@code': '36225735',
                    '@level': '1',
                    '@name': '36225735'},
                   {'@code': '36225738',
                    '@level': '1',
                    '@name': '36225738'},
                   {'@code': '36225744',
                    '@level': '1',
                    '@name': '36225744'},
                   {'@code': '36225745',
                    '@level': '1',
                    '@name': '36225745'},
                   {'@code': '36225756',
                    '@level': '1',
                    '@name': '36225756'},
                   {'@code': '36225758',
                    '@level': '1',
                    '@name': '36225758'},
                   {'@code': '36225759',
                    '@level': '1',
                    '@name': '36225759'},
                   {'@code': '36225769',
                    '@level': '1',
                    '@name': '36225769'}]}]},
'DATA_INF': {'NOTE': {'$': '当該数値がないもの',
                  '@char': '-'},
         'VALUE': [{'$': '0',
                    '@area': '36225727',
                    '@cat01': '0010',
                    '@cat02': '1',
                    '@unit': '世帯'},
                   {'$': '3',
                    '@area': '36225728',
                    '@cat01': '0010',
                    '@cat02': '1',
                    '@unit': '世帯'},
                   {'$': '2',
                    '@area': '36225738',
                    '@cat01': '0010',
                    '@cat02': '1',
                    '@unit': '世帯'},
                   {'$': '19',
                    '@area': '36225745',
                    '@cat01': '0010',
                    '@cat02': '1',
                    '@unit': '世帯'},......

CLASS_INFの["cat01"] ["cat02"] で条件を指定し、DATA_INFで絞ったデータの推定値を取得するというながれになっています。

今回は、["cat01"]が0060のものと0070のものが欲しいのでそちらで条件を絞ります。

こちらが最終的に欲しいデータを取得するコードになります。

import urllib
import urllib.request
import json
import pprint
from google.colab import files
import pandas as pd

appId = "8f3722a4fd1c48f94be0f02cfbb30baf7e9d3d17"
statsDataIds = []

#-------------StatsListの取得-------------

#url
url = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsList?"

#パラメーター
keys = {
       "appId"            : appId,
       "lang"             : "J" ,
       "statsCode"        : "00200521",
       "surveyYears"      : "201510",
       "searchKind"       : "2"
}
paramStr = urllib.parse.urlencode(keys)

rObj   = urllib.request.urlopen(url + paramStr)
resStr = rObj.read()
res = json.loads(resStr)

dataset = res["GET_STATS_LIST"]["DATALIST_INF"]["TABLE_INF"]
[statsDataIds.append(data["@id"]) for data in dataset if data["STATISTICS_NAME_SPEC"]["TABULATION_SUB_CATEGORY1"] == "世界測地系(1KMメッシュ)" and data["TITLE_SPEC"]["TABLE_NAME"] == "その3\u3000従業地・通学地集計及び世帯構造等基本集計に関する事項"]


#-------------StatsData労働者数の取得-------------
def get_workers():

   census_data_workers = []

   count = 0
   for i in statsDataIds:
       count=count+1
       print(str(count)+" (workers)")
       url = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsData?"
       keys = {
               "appId"            : appId,
               "lang"             : "J" ,
               "statsDataId"      : str(i)
       }

       paramStr = urllib.parse.urlencode(keys)
       rObj   = urllib.request.urlopen(url + paramStr)
       resStr = rObj.read()
       res = json.loads(resStr) 

       dataset = res["GET_STATS_DATA"]["STATISTICAL_DATA"]["DATA_INF"]["VALUE"]
       [census_data_workers.append([data["@area"], data["$"]]) for data in dataset if data["@cat01"] == "0060"]

   df_workers = pd.DataFrame(census_data_workers, columns=['meshcode', 'value'])
   df_workers.to_csv('df_workers.csv')
   files.download('df_workers.csv')

def get_students():

   census_data_students = []
   count = 0

   for i in statsDataIds:
       count=count+1
       print(str(count)+" (students)")
       url = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsData?"
       keys = {
               "appId"            : appId,
               "lang"             : "J" ,
               "statsDataId"      : str(i)
       }

       paramStr = urllib.parse.urlencode(keys)
       rObj   = urllib.request.urlopen(url + paramStr)
       resStr = rObj.read()
       res = json.loads(resStr) 

       dataset = res["GET_STATS_DATA"]["STATISTICAL_DATA"]["DATA_INF"]["VALUE"]
       [census_data_students.append([data["@area"], data["$"]]) for data in dataset if data["@cat01"] == "0070"]

   df_students = pd.DataFrame(census_data_students, columns=['meshcode', 'value'])
   df_students.to_csv('df_students.csv')
   files.download('df_students.csv') 

get_workers()
get_students()

colabのcodeはこちらです。

走らせてみてください!

(2つthread走らせると、ローカルではうまく行くのですがcolab上だとエラーが出るのでsingle threadで処理しました。)

CSVで17万行になりましたが取得できましたね!!

今回は、国勢調査の1kmメッシュ取得に関してまとめました!

次は、加工と加重平均計算について書いていこうと思うのでまたよろしくお願いします。

いいなと思ったら応援しよう!