不動産情報APIをPythonで利用してみた２　駅コード取得編

# 概要

不動産価格取得に関する記事の末尾で触れた駅コードの取得について紹介します．

https://qiita.com/AzukiImo/items/da60c0e5872c027829e7

不動産価格情報ライブラリAPIは，国土交通省が一般公開している不動産価格を取得を目的としたAPIでPythonでも利用することができます．登録作業をすることで利用することが可能となります．

不動産価格取得時に，**駅コード**を指定することで，指定した駅周辺の情報を取得することもできます．


# 1. 駅コードファイル
不動産情報ライブラリ[公式サイトの使い方](https://www.reinfolib.mlit.go.jp/help/apiManual/#titleApi4)によると駅コードについて，次のような説明が記載されています．

:::note
形式はNNNNNN（数字6桁） NNNNNN … 駅コード 
国土数値情報の駅データ（鉄道データの下位クラス）のグループコード（N02_005g）を指定します。 
https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N02-v3_1.html
を参照。
:::
実際に，[参照先のwebページ](https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N02-v3_1.html)に進むと，たくさんファイルがあり，どれをダウンロードするべきか迷います．

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725285/2b2ef363-0093-64ef-5fcd-493b63b6f27a.jpeg" width=60%>

一番新しい令和４年のファイル**N02-22_GML.zip**を選択します．

zipを展開するとN0-22で始まるファイルがいくつも現れます．今回はutf8ディレクトー内にある**N02-22_Station.shp**ファイルを利用します[^1]．


# 2. 駅コード取得
**N02-22_Station.shp**ファイルを読み込んで，駅データのグループコードであるN02_005gを探していきます．拡張子がshpのファイルは，GIS関連のファイルとなります．Pythonではgeopandasライブラリを利用してshpファイルを読み込みます．

:::note
インストールするライブラリ
* pip install geopandas
:::

[GeoPnadasの公式サイト](https://geopandas.org/en/stable/)に詳細な説明が記載されています．今回利用するのは，shpファイルを読み込む**read_file**だけです．

~~~python: shpファイルの読み込みと表示

import geopandas as gpd

filename = "./N02-22_GML/utf8/N02-22_Station.shp"
gdf = gpd.read_file(filename, encoding='utf8')
print(gdf.head())

# 	N02_001 	N02_002 	N02_003 	N02_004 	N02_005 	N02_005c 	N02_005g 	geometry
# 0 	11 	2 	指宿枕崎線 	九州旅客鉄道 	              二月田 	010112 	010112 	LINESTRING (130.63035 31.25405, 130.62985 31.2...
# 1 	23 	5 	沖縄都市モノレール線 	沖縄都市モノレール 	古島 	010127 	010127 	LINESTRING (127.70279 26.23035, 127.70309 26.2...
# 2 	24 	5 	東京臨海新交通臨海線 	ゆりかもめ 	お台場海浜公園 	004091 	004091 	LINESTRING (139.77818 35.62961, 139.77888 35.6...
# 3 	24 	5 	東京臨海新交通臨海線 	ゆりかもめ 	東京国際クルーズターミナル 	004128 	004128 	LINESTRING (139.77333 35.62109, 139.77288 35.6...
# 4 	24 	5 	東京臨海新交通臨海線 	ゆりかもめ 	テレコムセンター 	004144 	004144 	LINESTRING (139.78001 35.61791, 139.77932 35.6...
~~~

列の名前に**N0_005**や**N0_005g**が見えます．N0_005列には駅名が書かれています．N0_005g列には対応するコードが記載されています．

## 例
横浜駅の駅コードを取得するには，```gdf["N02_005"]```の値が```"横浜"```となる情報を抽出すれば良いので[^2]，

:::note
gdf[gdf["N02_005"]=="横浜"]
:::
のように表記することで表のデータを取得できます．

~~~Python
import geopandas as gpd

filename = "./N02-22_GML/utf8/N02-22_Station.shp"
gdf = gpd.read_file(filename, encoding='utf8')
print(gdf[gdf["N02_005"]=="横浜"])

#  	N02_001 	N02_002 	N02_003 	N02_004 	N02_005 	N02_005c 	N02_005g 	geometry
# 451 	12 	5 	みなとみらい21線 	横浜高速鉄道 	横浜 	004629 	004633 	LINESTRING (139.62275 35.46687, 139.62195 35.4...
# 477 	12 	3 	3号線 	横浜市 	横浜 	004636 	004633 	LINESTRING (139.62050 35.46462, 139.62031 35.4...
# 932 	12 	4 	本線 	京浜急行電鉄 	横浜 	004631 	004633 	LINESTRING (139.62237 35.46528, 139.62388 35.4...
# 4903 	12 	4 	本線 	相模鉄道 	横浜 	004633 	004633 	LINESTRING (139.62313 35.46693, 139.62179 35.4...
# 6057 	12 	4 	東横線 	東急電鉄 	横浜 	004628 	004633 	LINESTRING (139.62275 35.46687, 139.62195 35.4...
# 6833 	11 	2 	根岸線 	東日本旅客鉄道 	横浜 	004635 	004633 	LINESTRING (139.62170 35.46467, 139.62179 35.4...
# 7644 	11 	2 	東海道線 	東日本旅客鉄道 	横浜 	004634 	004633 	LINESTRING (139.62170 35.46467, 139.62179 35.4...
# 7649 	11 	2 	東海道線 	東日本旅客鉄道 	横浜 	004634 	004633 	LINESTRING (139.62133 35.46475, 139.62179 35.4...
~~~

表より，横浜駅の駅コードは**N02_005g**列を参照して**004633**と見つけることができます．

鎌倉駅の駅コードは

~~~Python
import geopandas as gpd

filename = "./N02-22_GML/utf8/N02-22_Station.shp"
gdf = gpd.read_file(filename, encoding='utf8')
print(gdf[gdf["N02_005"]=="鎌倉"])

# N02_001 N02_002 N02_003 	N02_004 	N02_005   N02_005c 	N02_005g 	geometry
# 2112 	12 	4 	江ノ島電鉄線 	江ノ島電鉄 	    鎌倉 	005059 	005055 	LINESTRING (139.55009 35.31849, 139.55009 35.3...
# 6608 	11 	2 	横須賀線 	東日本旅客鉄道 	鎌倉 	005055 	005055 	LINESTRING (139.55039 35.31826, 139.55038 35.3...
~~~
駅コードは**N02_005g**列の**005055**と見つけることができます[^3]．


# 3. 不動産価格の取得
駅コードを利用して不動産価格の取得を行います．すでにAPIキーの取得が済んでいるとします．API利用については，[不動産情報APIをPythonで利用してみた](https://qiita.com/AzukiImo/items/da60c0e5872c027829e7)を参考にしてください．

基本を確認しておきます．

:::note
APIで利用するURL
URL = https://www.reinfolib.mlit.go.jp/ex-api/external/XIT001?＜パラメータ＞
:::

:::note
パラメータ
* year: 取引時期（必須項目）
* priceClassification: 価格情報区分コード 01: 不動産取引価格．02: 成約価格． 
* quarter：取引時期（四半期）． 1 〜 4
* area: 都道府県コード． 1 〜 47
* city：市区町村コード
* station：駅コード（N02_005gの値）
:::
必須項目の取引時期と駅コードを設定すれば，駅コード周辺の不動産価格を取得できます．APIの取得キーを"1234xxxx"と表記しておきます．

### 具体例１．2020年横浜駅付近
2020年の横浜駅を中心とした不動産価格を取得するには，yearに2020を，stationに横浜駅のコード004633を指定し，APIを利用します[^4]．

~~~Python: 2020年横浜駅付近

import requests
import pandas as pd

url = "https://www.reinfolib.mlit.go.jp/ex-api/external/XIT001"
params = {"year": 2020, "station":"004633"}

# APIキーを入力　申請して取得した値
headers = {"Ocp-Apim-Subscription-Key": "1234xxxx"}
response = requests.get(url, headers=headers, params=params)

# 取得されたデータをデータフレームにして保存する
user_data = response.json()    # 取得したjson形式をpythonの辞書に変換
df = pd.DataFrame(user_data["data"])  # データフレームにする
df.to_csv("yokohama_2020.csv",index=False)  # ファイルに保存

print(df.head())

#   PriceCategory       Type Region MunicipalityCode Prefecture Municipality  ... CityPlanning CoverageRatio FloorAreaRatio      Period Renovation Remarks
# 0     不動産取引価格情報   中古マンション等                   14102       神奈川県      横浜市神奈川区  ...         商業地域            80            500  2020年第4四半期        未改装        
# 1     不動産取引価格情報   中古マンション等                   14102       神奈川県      横浜市神奈川区  ...         商業地域            80            400  2020年第4四半期       改装済み        
# 2     不動産取引価格情報   中古マンション等                   14102       神奈川県      横浜市神奈川区  ...         工業地域            60            200  2020年第1四半期        未改装        
~~~

取得したデータはJSON形式になるので，必要に応じて変換して必要な部分を保存することとなります．サンプルコードでは，辞書に一旦変換しています．
~~~Python:user_dataの値
{'status': 'OK', 'data': [{'PriceCategory': '不動産取引価格情報', 'Type': '中古マンション等', 'Region': '', 'MunicipalityCode': '14102', 'Prefecture': '神奈川県', 'Municipality': '横浜市神奈川区', 'DistrictName': '台町', 'TradePrice': '9300000', 'PricePerUnit': '', 'FloorPlan': '１Ｋ', 'Area': '15', 'UnitPrice': '', 'LandShape': '', 'Frontage': '', 'TotalFloorArea': '', 'BuildingYear': '1993年', 'Structure': '', 'Use': '', 'Purpose': 'その他', 'Direction': '', 'Classification': '', 'Breadth': '', 'CityPlanning': '商業地域', 'CoverageRatio': '80', 'FloorAreaRatio': '500', 'Period': '2020年第4四半期', 'Renovation': '未改装', 'Remarks': ''}, {'PriceCategory': '不動産取引価格情報'...
~~~
dataキーだけが必要な部分となります．データフレームに変換したいので，

~~~Python
df = pd.DataFrame(user_data["data"])
~~~
によって変換しています．


### 具体例２． 2023年鎌倉駅付近
~~~Python:2023年鎌倉駅付近

import requests
import pandas as pd

url = "https://www.reinfolib.mlit.go.jp/ex-api/external/XIT001"
params = {"year": 2023, "station": "005055"} 

# APIキーを入力　申請して取得した値
headers = {"Ocp-Apim-Subscription-Key": "1234xxxx"}
response = requests.get(url, headers=headers, params=params)

# 取得されたデータをデータフレームにして保存する
user_data = response.json()    # 取得したjson形式をpythonの辞書に変換
df = pd.DataFrame(user_data["data"])  # データフレームにする
df.to_csv("kamakura_2023.csv",index=False)  # ファイルに保存

print(df.head())

#  	PriceCategory 	Type 	Region 	MunicipalityCode 	Prefecture 	Municipality 	DistrictName 	TradePrice 	PricePerUnit 	FloorPlan 	... 	Purpose 	Direction 	Classification 	Breadth 	CityPlanning 	CoverageRatio 	FloorAreaRatio 	Period 	Renovation 	Remarks
# 0 	成約価格情報 	宅地(土地と建物) 	NaN 	14204 	神奈川県 	鎌倉市 	浄明寺 	67000000 	NaN 	４ＬＤＫ 	... 	NaN 	南 	公道 	6.0 	第１種低層住居専用地域 	40.0 	80.0 	2023年第４四半期 	NaN 	NaN
# 1 	不動産取引価格情報 	宅地(土地) 	住宅地 	14204 	神奈川県 	鎌倉市 	材木座 	130000000 	1200000.0 	NaN 	... 	住宅 	北 	市道 	1.8 	第１種中高層住居専用地域 	60.0 	200.0 	2023年第1四半期 	NaN 	NaN
# 2 	不動産取引価格情報 	宅地(土地) 	住宅地 	14204 	神奈川県 	鎌倉市 	材木座 	60000000 	890000.0 	NaN 	... 	住宅 	南 	私道 	3.0 	第１種中高層住居専用地域 	60.0 	150.0 	2023年第1四半期 	NaN 	NaN
~~~
paramsの値に2023と鎌倉の駅コードを記して完成です．鎌倉駅周辺の不動産価格なのですが，その取得範囲は，鎌倉市・逗子市の一部に広がっています．

これで，駅周辺の不動産価格マスターに一歩近づきました:sweat:

# 注
[^1]: utf8ディレクトリ以外のファイルは，Windows環境のものだと思われます．拡張子がshpなのでGISソフトでの利用を前提としているのかな？
[^2]: データフレームの名前をgdfとしているので，``gdf["N02_005"]``という形でN02_005列のデータになります．
[^3]: N02_005c列は，「駅の緯度を降順に並び替えて付加した一意の番号」と公式サイトに記載がありました．
[^4]: yearは数値，stationは文字列で値を与える点に注意してください．