東京都の地下鉄駅データを、隣駅が分かるように加工する
「画面を見ないでできる」「電車にまつわる」シンプルなゲームを作ることにしました。
その準備として、東京の地下鉄駅のデータを整理してみます。
データ入手
駅データ.jpさんのデータがとても便利でした。
無料版を使わせていただきました。
ゴール
とりあえず、隣り合う駅が分かる形の表データを目指します。
対象は地下鉄路線のみで、接続や乗り入れは考えません。例えば浅草線は、泉岳寺から品川へ行けますが京急なので無視。
あと、つくばエクスプレスも無視します。秋葉原もつくば駅も地下プラットフォームですが、あれって地下鉄の分類じゃないですよね?
処理
まずは路線種別データから地下鉄路線の「line_cd」(路線コード)を抜き出して、そのうえで駅一覧データからその line_cd の駅データを取り出します。
地下鉄路線の絞り込み。「東京メトロ」と「都営地下鉄」しかないので簡単です。
import pandas as pd
line_df = pd.read_csv('line20240426free.csv')
tokyo_subway_lines = [x for x in line_df['line_name'].unique() if '東京メトロ' in x or '都営' in x] # 地下鉄名称一覧. line_cdでもよい
tokyo_subway_line_df = lines[lines['line_name'].isin(tokyo_subway_lines)] # これ
# 辞書型にしてみる
tokyo_subway_line_cd = {x:y for x, y in zip(tokyo_subway_line_df['line_cd'], tokyo_subway_line_df['line_name'])}
tokyo_subway_line_cd
出力 ↓
{
28001: '東京メトロ銀座線',
28002: '東京メトロ丸ノ内線',
28003: '東京メトロ日比谷線',
28004: '東京メトロ東西線',
28005: '東京メトロ千代田線',
28006: '東京メトロ有楽町線',
28008: '東京メトロ半蔵門線',
28009: '東京メトロ南北線',
28010: '東京メトロ副都心線',
99301: '都営大江戸線',
99302: '都営浅草線',
99303: '都営三田線',
99304: '都営新宿線'
}
これを使って、駅のデータから地下鉄駅を絞り込みます。
stations = pd.read_csv('station20240426free.csv')
subway_stations_df = stations[stations['line_cd'].isin(tokyo_subway_line_cd.keys())]
subway_stations_df.__len__() # 291
乗り換え駅はダブりますが、291駅もありました。
という公式情報があるので、まぁ大体あっていそうです。逆に何が一致しないんでしょう?
ここからが少し趣味要素です。隣駅の「station_cd」(駅コード)が分かるようにします。
駅データ.jpより、隣り合う駅の情報がcsvにまとめられているので、これを上のデータに結合します。
joins = pd.read_csv('join20240426.csv')
# right: station_cdが大きい隣駅 / left: 自駅よりstation_cdが小さい隣駅 とする
stations_neighbor_df = subway_stations_df.merge(joins[['station_cd1', 'station_cd2']], left_on='station_cd', right_on='station_cd1', how='left')
stations_neighbor_df.drop(columns=['station_cd1'], inplace=True)
stations_neighbor_df.rename(columns={'station_cd2': 'right_cd'}, inplace=True)
stations_neighbor_df = stations_neighbor_df.merge(joins[['station_cd1', 'station_cd2']], left_on='station_cd', right_on='station_cd2', how='left')
stations_neighbor_df.drop(columns=['station_cd2'], inplace=True)
stations_neighbor_df.rename(columns={'station_cd1': 'left_cd'}, inplace=True)
ここまできて、致命的な弱点に気づきました。三叉路になっている駅の存在です。今作っているデータでは、隣り合う駅は二つまで、というのが暗黙の了解になっています。しかしながら地下鉄にも、枝分かれ路線がいくつかあります。考慮漏れ。
幸運なことに、これまでの処理でそのような駅は行が二つできているはずです。なので簡単に可視化できます。私が思いつく限りでは都庁前駅(大江戸線)、中野坂上駅(丸の内線)でした。仮説が正しいか確認しましょう。
# groupbyのあとにgroupsを呼ぶと、一覧を辞書形式で出せる
for k,v in stations_neighbor_df.groupby('station_cd').groups.items():
if len(v)>1:
display(stations_neighbor_df[stations_neighbor_df['station_cd']==k])
結果がこちら。あたっててなんかうれしい。
station_cd | station_g_cd | station_name | line_cd | lon | lat | address | right_cd | left_cd |
---|---|---|---|---|---|---|---|---|
2800220 | 2800220 | 中野坂上 | 28002 | 139.68291 | 35.69792 | 中野区中央2-1-2 | 2800221.0 | 2800219.0 |
2800220 | 2800220 | 中野坂上 | 28002 | 139.68291 | 35.69792 | 中野区中央2-1-2 | 2800226.0 | 2800219.0 |
station_cd | station_g_cd | station_name | line_cd | lon | lat | address | right_cd | left_cd |
---|---|---|---|---|---|---|---|---|
9930101 | 9930101 | 都庁前 | 99301 | 139.69257 | 35.690551 | 新宿区西新宿2-8-1 | 9930102.0 | 9930128.0 |
9930101 | 9930101 | 都庁前 | 99301 | 139.69257 | 35.690551 | 新宿区西新宿2-8-1 | 9930129.0 | 9930128.0 |
これらをどうするかはお好み。あたらしくstation_cdをきって別駅にするのも用途によってはありかと思います。たとえば
stations_neighbor_df.loc[39, 'station_cd'] = 2800228+1
stations_neighbor_df.loc[39, 'station_name'] = '中野坂上 方南町方面'
stations_neighbor_df.loc[186, 'station_cd'] = 9930138+1
stations_neighbor_df.loc[186, 'station_name'] = '都庁前 飯田橋方面'
stations_neighbor_df.loc[186, 'left_cd'] = 9930129
地上路線だとこういうのさらに増えそうなので、考えたくないです。。
ともあれ目標のデータが達成できました。
Discussion