2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

駅ごとにその駅を最寄り駅としている人の数を求めてみた(練馬区編)

Last updated at Posted at 2022-12-18

はじめに

本記事では練馬区の鉄道駅ごとの最寄り駅人口を求めます。
筆者が練馬区民のため対象を練馬区としていますが、コードの一部を変えるだけであらゆる地域の最寄り駅人口を求めることができます。

今回のコードはヘルシンキ大学が公開しているGISに関する教材を元にしています。
筆者はそちらの教材を勉強した後のアウトプットでこの記事を書いています。
GISについて勉強してみたい方はぜひそちらを使ってみてください。そちらの教材についての質問があればQiitaのコメントで議論させていただけると、筆者も勉強になり大変嬉しいです。

※本記事はGoogle Colab上で使用することを想定しています。ローカル環境でのコード実行時には事前に必要なライブラリのインストールが必要になります。

扱うデータについて

本記事では表1のデータを扱います。
練馬区であっても隣接する市区町村の鉄道駅が最寄り駅のケースがあると考えて、練馬区と隣接する埼玉県(新座市、和光市、朝霞市)のデータも取得します。
ちなみに練馬区は、板橋区、中野区、杉並区、豊島区、西東京市、武蔵野市、東京以外では北側が埼玉県の新座市、和光市、朝霞市と隣接しているようです。(※2)

扱うデータとデータ取得先
東京都、埼玉県の町丁目ごとの境界データ:e-Stat
東京都、埼玉県の町丁目ごとの人口データ:e-Stat
全国の鉄道データ:国土交通省

e-Statのデータは下記コードでもダウンロードが可能です。

import download

data_fp = "データを格納するフォルダパスをここに入力してください"

# 東京都の町丁目ごとの境界データをダウンロードする
download.download(
  "https://www.e-stat.go.jp/gis/statmap-search/data?dlserveyId=A002005212020&code=13&coordSys=1&format=shape&downloadType=5&datum=2000",
   data_fp,
   kind="zip",
   replace=True,
)

# 東京都の町丁目ごとの人口データをダウンロードする
download.download(
   "https://www.e-stat.go.jp/gis/statmap-search/data?statsId=T001081&code=13&downloadType=2",
   data_fp,
   kind="zip",
   replace=True,
)

# 埼玉県の町丁目ごとの境界データをダウンロードする
download.download(
  "https://www.e-stat.go.jp/gis/statmap-search/data?dlserveyId=A002005212020&code=11&coordSys=1&format=shape&downloadType=5&datum=2000",
   data_fp,
   kind="zip",
   replace=True,
)

# 埼玉県の町丁目ごとの人口データをダウンロードする
download.download(
   "https://www.e-stat.go.jp/gis/statmap-search/data?statsId=T001081&code=11&downloadType=2",
   data_fp,
   kind="zip",
   replace=True,
)

練馬区と隣接する市区町村の鉄道駅を地図に表示する

まずは必要なライブラリをインポートします。

!pip install geopandas
!pip install japanize_matplotlib
!pip install mapclassify
!pip install rtree
import rtree
import mapclassify
import japanize_matplotlib
import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import folium
import os
from shapely.geometry import Point, LineString, Polygon
from shapely.ops import nearest_points

まずはGeoPandasで鉄道データを取得します。
鉄道駅のデータは国土交通省から取得します。令和3年の鉄道駅のデータをダウンロードして、datasetフォルダに格納しておいて、Geopandasで読み込みます。

fp =  os.path.join(data_fp, 'N02-21_Station.geojson')
StationData = gpd.read_file(fp)r
StationData.head()

鉄道名と鉄道駅名、それらのgeometryが取得できています。
image15.png

取得したデータのgeometryはLINESTRING型で線データになっています。対象駅から下り方面への次の駅までの軌跡の座標データが入っています。今回は駅のPOINTデータが必要なため、それぞれの線の開始点のデータを取得します。

get_point = lambda row:Point(row.coords[0])
StationData["geometry"] = StationData["geometry"].apply(get_point)
StationData.head()

POINTデータを取得することができました。
image10.png

必要なカラムを取り出して、カラム名を変更します。

StationData = StationData.loc[:, ["N02_005", "geometry"]]
StationData = StationData.rename(columns={'N02_005': 'StationName'})
StationData.head()

image2.png

東京都と埼玉県の境界データをGeoPandasで取得します。

fp_tokyo =  os.path.join(data_fp, 'r2ka13.shp')
fp_saitama =  os.path.join(data_fp, 'r2ka11.shp')

tokyo_geo = gpd.read_file(fp_tokyo)
saitama_geo = gpd.read_file(fp_saitama)

東京都と埼玉県のデータから、上で述べた練馬区と隣接する市区町村のデータを抽出して、マージします。

def gdf_arrange(gdf, city_list):
 temp = gdf.loc[:, ['geometry', 'CITY_NAME', 'KEY_CODE']]
 temp['KEY_CODE'] = temp['KEY_CODE'].astype(str)
 temp = temp[temp['CITY_NAME'].isin(city_list)]
 return temp

tokyo_list = ['練馬区', '板橋区', '中野区', '杉並区', '豊島区', '西東京市', '武蔵野市']
saitama_list = ['新座市', '和光市', '朝霞市']

tokyo_geo = gdf_arrange(tokyo_geo, tokyo_list)
saitama_geo = gdf_arrange(saitama_geo, saitama_list)

geo = tokyo_geo.append(saitama_geo)
geo.head()

練馬区と隣接する市区町村のポリゴンデータを取得することができました。
image12.png

練馬区と隣接する市区町村のポリゴンデータ(geo)と交差する鉄道駅のデータを抽出します。GeoPandasにはsjoin(Spatial join)というmethodが実装されており、ポイントデータやポリゴンデータを空間結合することができます。"intersects"、"within"、"contains"、”Covers”というオプションがありますが、今回はポリゴンデータ内にあるポイントデータを探索するので、”within”を用います。オプションの説明は以下のサイトが参考になります。
https://mentin.medium.com/which-predicate-cb608b470471

Station_point = gpd.sjoin(StationData, geo, how="inner", op="within")
Station_point = Station_point.loc[:, ["StationName", "geometry"]]
Station_point.head()

対象の鉄道駅を抽出することができました。
image8.png

望んだデータが得られているか、地図に可視化して確かめてみます。

fig, ax = plt.subplots(figsize=(15,8))
geo.plot(ax=ax)
Station_point.plot(ax=ax, color='red', markersize=20)

対象地域のポリゴンデータとそれらと交差する鉄道駅のポイントデータを得られていることが確認できました。
image.png

町丁目ごとの最寄り駅を求める

まず町丁目ごとの重心座標を求めます。

geo['centroid'] = geo.centroid
geo.head()

各地域の重心座標が求まり、”centroid”カラムに入りました。
image4.png

複数のポイントから、あるポイントと最も近いポイントを探索してそのポイントの情報を返す関数を定義します。あるポイントと最も近いポイントを探索するメソッドはnearest_pointsで実装されています。今回は最も近いポイントの駅名を得たいため、求まったポイントの行を取得し、その行の指定したカラムの値を返しています。

def get_nearest_values(row, other_gdf, point_column='geometry', value_column="geometry"):
   # 駅のポイントをマルチポイントにする
   other_points = other_gdf["geometry"].unary_union

   # 地域のポリゴンの重心と最も近い駅のポイントを取得
   nearest_geoms = nearest_points(row[point_column], other_points)

   # 上で求めたポイントの行を取得
   nearest_data = other_gdf.loc[other_gdf["geometry"] == nearest_geoms[1]]

   # 上で求めたポイントの指定したカラムの値を取得
   nearest_value = nearest_data[value_column].values[0]
   return nearest_value

上で定義した関数(get_nearest_values)を使って、各町丁目の重心から最も近い鉄道駅名を取得します。

geo["nearest_loc"] = geo.apply(get_nearest_values, other_gdf=Station_point, point_column="centroid", value_column="StationName", axis=1)
geo.head()

“nearest_loc”カラムに駅名が入りました。
image16.png

正しく最寄り駅を取得できているか、地図に表示して確認してみます。
“nearest_loc”カラムの値ごとに色を塗ったような地図を表示し、鉄道駅のポイントデータをプロットします。

fig, ax = plt.subplots(figsize=(15,8))
geo.plot(ax=ax, column="nearest_loc" ,cmap="tab20")
Station_point.plot(ax=ax, color='black', markersize=40)

各町丁目ごとに最寄り駅を取得できている様子がわかります。
image9.png

駅ごとにその駅を最寄り駅としている人の数を求める

まずは上で求めた練馬区と隣接する市区町村のポリゴンデータから、練馬区のデータのみを抽出します。

geo_nerima = geo[geo["CITY_NAME"] == "練馬区"]
geo_nerima.head()

練馬区のデータを抽出することができました。
image3.png

鉄道駅のポイントデータから、練馬区のポリゴンデータ内に存在するものを抽出して、地図に表示します。

Station_point_nerima = gpd.sjoin(StationData, geo_nerima, how="inner", op="within")
Station_point_nerima = Station_point_nerima.loc[:, ["StationName", "geometry"]]

fig, ax = plt.subplots(figsize=(15,8))

geo_nerima.plot(ax=ax, column="nearest_loc",cmap="tab20")

Station_point_nerima.plot(ax=ax, color='black', markersize=40)

練馬区のみを抽出して表示することができました。
image1.png

Pandasで人口データをダウンロードします。必要なカラムのみを抽出やNaNの行を削除する等のデータの前処理を行います。この人口データの前処理についてはこちらの記事で記載しておりますので、ぜひご覧ください。

fp_pop =  os.path.join(data_fp, 'tblT001081C13.txt')
data = pd.read_csv(fp_pop, encoding="CP932", dtype={'KEY_CODE': str, 'HYOSYO': str})
data = data.loc[:, ["KEY_CODE", "HYOSYO","CITYNAME","NAME", "T001081001"]]
data = data[data['HYOSYO'] == "4"]
data = data.rename(columns={'T001081001': 'pop'})
data['KEY_CODE'] = data['KEY_CODE'].astype(str)
data = data.replace('-', '0')
data['pop'] = data['pop'].astype(float)
data.dropna(inplace=True)
data.head()

町丁目ごとの人口データを取得することができました。
image14.png

練馬区の町丁目ごとの最寄り駅のデータ(geo)と人口データ(data)をマージします。

geodata_nerima =  geo_nerima.merge(data, on='KEY_CODE')
geodata_nerima.head()

マージすることができました。
image5.png

最寄り駅が同じ町丁目の人口の合計値を取得します。このような場合はPandasのgroupby()かGeoPandasのdissolve()を適用することでデータを結合できます。今回は最寄り駅名(nearest_loc)をキーとしてdissolved()でデータを結合します。

dissolved = geodata_nerima.dissolve(by="nearest_loc", aggfunc={"pop": "sum"})
dissolved

最寄り駅ごとの人口を集計することができました。
image11.png

鉄道駅ごとの最寄り駅人口を地図に表示します。

fig, ax = plt.subplots(1, figsize=(10, 8))
dissolved.plot(ax=ax, column="pop", legend=True)
Station_point_nerima.plot(ax=ax, color='black', markersize=40)

傾向として、西側の方が最寄り駅人口が多そうです。
image6.png

最寄り駅人口をグラフに表示します。

data_nerima = pd.DataFrame(dissolved.drop(columns='geometry'))
fig, ax = plt.subplots(1, figsize=(10, 8))
data_nerima.plot.barh(ax=ax)

練馬区の鉄道駅ごとの最寄り駅人口を求めることができました。
練馬区では「大泉学園駅」が最寄り駅の人口が最も多いようです。
image7.png

西武池袋線の駅別乗降人員都営大江戸線の駅別乗降人員を見てみると、大泉学園駅の乗降人員は練馬区の中では練馬駅に次いで2番目に多いようです。練馬駅は西武池袋線と都営大江戸線の乗換駅であるため必然的に利用者が多くなると思われます。乗換駅を除いた中では大泉学園駅が最も利用されているということになります。今回の結果とも合致していそうです。また、都営大江戸線の延伸計画では、大泉学園周辺の鉄道空白地域の改善を目的の一つとして謳っており、大泉学園駅を最寄駅とする人が多いことが伺えます。

まとめ

今回は町丁目ごとのポリゴンデータ、人口データ、鉄道駅データを使って鉄道駅ごとの練馬区の最寄り駅人口を求めてました。
町丁目の重心から最も近い駅を求めてその町丁目の人口の最寄り駅としているため、少し精度は気になりますが、概ね近い値を求められていると思われます。

これからも勉強しながら成果を記事にしていこうと思うので、よろしくお願いします。

参考文献

※1 ヘルシンキ大学 GIS教材
https://autogis-site.readthedocs.io/en/2021/

※2 さとふる 東京都練馬区の地域情報
https://www.satofull.jp/static/html/municipality/131202/#:~:text=%E9%9A%A3%E6%8E%A5%E3%81%99%E3%82%8B%E5%8C%BA%E3%81%AF%E6%9D%BF%E6%A9%8B,%E3%81%AA%E3%81%84%E3%81%AA%E3%81%A0%E3%82%89%E3%81%8B%E3%81%AA%E5%9C%B0%E5%BD%A2%E3%81%A7%E3%81%99%E3%80%82

※3 Geopandasリファレンス
https://geopandas.org/en/stable/gallery/choropleths.html

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?