AI要約
IATA空港コード(HNDやNRTなど)が枯渇しているという説を、実際にスクレイピングで収集したデータを使って検証しました。3文字の組み合わせに潜む制約や割当傾向を分析し、コード枯渇の現実味を定量的に探っています。
やること
IATA空港コード(IATA airport code)は空港に付けられる3文字のコードです。羽田空港は「HND」、成田空港は「NRT」、伊丹空港は「ITM」となっていてわかりやすい。
雑学でおなじみ、関西国際空港(Kansai International Airport)はなぜ「KIX」なのか?当初「KIA」を取りたかったらしいですが、パプアニューギニアのカイアピット空港(Kaiapit Airport)がすでにKIAを使っていたため、残りものからなくなく「KIX」を選んだとか。
ここで、皆さん気になってしょうがないと思います。
263通りって枯渇しない?
人類はIPv4アドレス枯渇問題から何を学んだのか。いや、空港コードのほうが先に生まれたのですが。
疑問は解消しましょう。IATA空港コードがどれくらい埋まっているのかを調べてみました。
IATA空港コードの一覧
Wikipediaにも一覧がありますが、けっこう漏れがあるようです。
IACEトラベルのサイトに掲載されているリストが網羅性が高そうでしたので、こちらを使用させていただきました。
「vcscraping」でお手軽Webスクレイピング
誰も使っていないお手軽Webスクレイピングパッケージ「vcscraping」。ちょっとバグあるし、メンテナンスしてないし、仕方ない。
pipインストールしておきます。
pip install vcscraping
サイトURLを指定してインスタンスを立ち上げ、htmlの適当な範囲をprintしてみる。
import numpy as np
import matplotlib.pyplot as plt
from vcscraping import vcscraping
#URL
url = 'https://iace.co.jp/bts/useful/detail/agent_2.html'
#インスタンス初期化(シングルモード)
myscraping = vcscraping(url)
print(myscraping.html[20200:20600])
mode = <single page>
>空港<br class="spbr">コード</th>
<th>空港名</th>
<th>国名</th>
</tr>
</thead>
<body>
<tr>
<td>AAA</td>
<td>Anaa Airport</td>
<td>フランス領ポリネシア</td>
</tr>
<tr>
<td>AAB</td>
<td>Arrabury Airport</td>
<td>オーストラリア</td>
</tr>
<tr>
<td>AAC</td>
<td>El Arish International Airport</td>
<td>エジプト</td>
</tr>
<tr>
<td>AAD</td>
<td>Ad-Dabbah Airport</td>
<td>スーダン</td>
</tr>
<tr>
<td>AAE</td>
これをよく見て、「AAA」と「AAB」を共通で挟みうちしているprefixとsuffixを見つけます。このサイトは改行コードが「\r\n」であることに注意しましょう(誰がわかるんだ)。次のように決めて全件取得しました。
#prefix, suffix
pre = '<tr>\r\n<td>'
suf = '</td>\r\n'
#要素をすべて取得
texts, starts, ends = myscraping.get_between_all(pre, suf)
print(texts[:10])
print(texts[-10:])
mode = <single page>
found = 7888
['AAA', 'AAB', 'AAC', 'AAD', 'AAE', 'AAF', 'AAG', 'AAH', 'AAI', 'AAJ']
['ZVA', 'ZVG', 'ZVK', 'ZWA', 'ZWL', 'ZWS', 'ZYI', 'ZYL', 'ZZU', 'ZZV']
7888件抽出できました。めっちゃ多いですね。
ちなみにvcscrapingにはprefixとsuffixの自動検出機能があるのですが、ポンコツなのであまり使っていません。需要があればパッケージ修正します~
統計と可視化
スリーレターなので3次元配列にTrue/Falseを埋めていって、統計を出してみます。
#全組み合わせをチェック、使われていればTrueに
heatmap = np.zeros((26, 26, 26), bool)
for i, l1 in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
for j, l2 in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
for k, l3 in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
if l1 + l2 + l3 in texts:
heatmap[i, j, k] = True
#頭文字別の統計
for i, l1 in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
rate = round(100 * np.sum(heatmap[i]) / 26**2, 1)
print(f'{l1}-- {np.sum(heatmap[i])}/{26**2} ({rate}%) used')
#全統計
rate = round(100 * np.sum(heatmap) / 26**3, 1)
print(f'--- {np.sum(heatmap)}/{26**3} ({rate}%) used')
A-- 526/676 (77.8%) used
B-- 594/676 (87.9%) used
C-- 544/676 (80.5%) used
D-- 279/676 (41.3%) used
E-- 247/676 (36.5%) used
F-- 217/676 (32.1%) used
G-- 349/676 (51.6%) used
H-- 311/676 (46.0%) used
I-- 261/676 (38.6%) used
J-- 211/676 (31.2%) used
K-- 498/676 (73.7%) used
L-- 465/676 (68.8%) used
M-- 611/676 (90.4%) used
N-- 187/676 (27.7%) used
O-- 198/676 (29.3%) used
P-- 322/676 (47.6%) used
Q-- 68/676 (10.1%) used
R-- 200/676 (29.6%) used
S-- 428/676 (63.3%) used
T-- 301/676 (44.5%) used
U-- 117/676 (17.3%) used
V-- 132/676 (19.5%) used
W-- 136/676 (20.1%) used
X-- 95/676 (14.1%) used
Y-- 466/676 (68.9%) used
Z-- 118/676 (17.5%) used
--- 7881/17576 (44.8%) used
ご覧ください。「A○○」は78%使用されています。「M○○」にいたっては90%使用されています。Mから始まる空港はうかつに建設できないですね。全アルファベットの総合では45%(7881/17576)が使用済みでした。あれ?意外と空きがある・・・?
頭文字ごとにヒートマップで見てみましょう。
#頭文字別のヒートマップ
for i, l1 in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
fig = plt.figure()
plt.imshow(heatmap[i], cmap='Greys', vmin=-0.2, vmax=1.2)
plt.title(f'{l1}--')
plt.xticks(range(26), list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))
plt.yticks(range(26), list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))
plt.xlabel('3rd')
plt.ylabel('2nd')
plt.gca().xaxis.tick_top()
plt.gca().xaxis.set_label_position("top")
plt.show()
A~O

P~Z

(軸が2rdと3ndになっているのは気にしないでください)
黒マスが使用済みです。横方向は2文字目が同じものです。例えば「E○○」グループは比較的空きがありますが、「EL○」はすべて埋まっていることがわかります。他にも横筋の傾向が見られますね。縦筋の傾向はなさそうです。本当かな?
おわりに
今回使用させていただいたサイトには空港名と国名も載っています。今回のコードを参考に国別の統計を出してみても面白いかもしれませんね。ちなみに「Y○○」はほとんどがカナダです。何か理由がありそうですね。

自由研究にピッタリ!