LoginSignup
14
9

More than 1 year has passed since last update.

pythonでcsvにある経度緯度から一気に距離を算出する(直線距離)

Last updated at Posted at 2021-12-09

Python Advent Calendar 2021 10日目
記事書き忘れてて、当日の早朝に急いで書いた(小声)

Advent Calendarに初めて載せます!

はじめに

データ分析で特徴量を作るときに距離を入れたいときありませんか?

10個の経路検索をするときはgooglemapでやればすぐ終わりますが、
1000個の経路検索やるときはどうでしょうか
googlemapでいちいちやるのは現実的ではありません

色々解決方法はありますが、今回は一番手っ取り早い方法として、経度緯度から直線距離を算出します。

結論から言うとpythonのGeoPyを使います。
研究で使い、計算も早くめちゃくちゃ便利だったので、今回紹介する事にしました。

image.png

GeoPyとは

シンプルに一言で言うならば、経度緯度から直線距離を出してくれるツールです。
pythonのパッケージでpipで入れればすぐ使う事ができます。

pip install geopy

もう少しちゃんと説明するとGIS系のパッケージで、測地線距離と大円距離という二つの距離がありますが、ざっと調べた感じ測地線距離がよく使われていそうです。
測地線距離→楕円である地球上で、2 ポイント間の最短距離を結んだ曲線
IBM 測地距離
大円距離→球面上の2点間の長さが最短となる距離
wikipedia 大円距離

この記事によると大円距離の方が早いらしいけど、若干精度が落ちるらしい?
要するに使い分けるとよさそうですね。

実際に距離を算出してみる

では実際に距離を算出します。
今回は測定距離で直線距離を測ってみます。

まずはgeopyをインポート

from geopy.distance import geodesic

次に経度緯度をセットします。
今回は北海道コンサドーレ札幌のホームスタジアムである札幌ドームからジュビロ磐田のヤマハスタジアムまでの距離を算出しています。

#経度緯度セット sapporo=札幌ドーム iwata=ヤマハスタジアム
sapporo = (43.015136248873034, 139.76608399999998)
iwata = (35.675069, 139.763328)

そして距離をこのように計算します。
メートルやキロメートルどちらでも算出できます。
やりたい分析に対して、その時々で使い分けるといいと思います。

#メートル 934721.8398158915
distance_m = geodesic(sapporo, iwata).m  
#キロメートル 934.7218398158915
distance_km = geodesic(sapporo, iwata).km

札幌ドームからヤマハスタジアムまでは約935km(約934722m)のようです。

ちなみに大円距離で算出する場合は以下のように書きます。

from geopy.distance import great_circle

#メートル 936134.921225789
distance_m_ver2 = great_circle(sapporo, iwata).m
#キロメートル 936.134921225789
distance_km_ver2 = great_circle(sapporo, iwata).km

大円距離の場合は約936km(約936134m)でした。
やはり精度を求めたいときは測定距離でやるといいのかもしれません。

[実践]csvにある経度緯度から一気に距離を算出する

前章で直線距離の算出方法を説明しました。
ただこれだけだとgeopyのありがたみが伝わらないと思うので、実践編として経度緯度があるcsvから一気に距離を算出する方法を解説します。

あくまでも今回は紹介用なのでサンプルが少ないですが、以下のcsvを用意しました。
今回は来年j1に上がるジュビロ磐田のヤマハスタジアムから来年のj1勢のスタジアムまでの距離を測ってみましょう。

このようにデータが入っています。
0行目がヤマハスタジアム、1行目からが来年のj1勢です。
image.png

import pandas as pd
from geopy.distance import geodesic

#csv読み込み
df = pd.read_csv("data.csv")

次にfor分を使ってそれぞれヤマハスタジアムから各スタジアムまでの直線距離を出し、distance列に格納します。

for i in range(0, 18):
    iwata = ((df.at[0, 'Y_CODE']), (df.at[0, 'X_CODE']))
    destination = ((df.at[i, 'Y_CODE']), (df.at[i, 'X_CODE']))
    x = geodesic(iwata, destination).m
    df.at[0+i, 'distance'] = x  

するとデータフレームにdistance列ができ、以下のようになります。
(今回はメートルにしました)
image.png

これでcsvに吐き出したりして分析の特徴量に使う事ができます。

ちなみに計算時間は0.006001949310302734[sec]
一瞬です。今回はサンプルが少なかった為、あまり時間は意味ありませんが。

ちなみに筆者が前に約68万個の直線距離を一気に算出して2分
経路検索をして約50分かかった為、geopyはかなり早く計算できる事が分かります。

さいごに

今回はサンプル数が少なかった為、あまりgeopyの便利さを伝えられたか微妙な所ですが。

分析で距離に関する特徴量を使いたくなったら、経路検索だと車とか徒歩とかややこしい上に時間がかかる為、直線距離でやってみちゃうのが一番早いと思います。
(直線距離でも距離という概念を特徴量に入れられるから経路検索距離と対して結果は変わらないはず)

実は効率の良い方法を紹介しときながら、今回のスタジアムはいちいち経度緯度をgooglemapから調べるというとても効率の悪い方法でやっています。笑
ただ今オープンデータが充実していて、
統計GISデータの境界データには経度緯度が入っていて、国土数値情報などと組み合わせるとすぐ位置情報付きデータになり、距離を計算できるため、めちゃくちゃ便利です。

ぜひ使ってみてください。

pythonを使った経路検索の方法もあるのですが、直線距離と違い少しややこしく長くなるので、いいねの数が多くなったら、頑張って書きます。(笑)

こんな記事書きながら実は地理系詳しくないから、間違いの指摘や補足あればお願いします。

さいごのさいごに...

ある拠点があったときに経度緯度を簡単に集められる方法探しています。知っている方いたら、コメントお願いしますm(__)m
(あるいは住所から自動的に経度緯度を検索してくれたり)
例えば上のスタジアムの経度緯度を調べてくれる方法があったら、めっちゃ知りたいです。

14
9
3

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
14
9