8

複数の緯度と経度の座標間の距離を計算するのに苦労しています。要するに、数学またはgeopyを使用するチュートリアルが多数見つかりました。これらのチュートリアルは、座標の 1 つのセット (または 2 つの一意の場所) 間の距離を見つけたい場合に最適です。ただし、私の目的は、出発地と目的地の座標の組み合わせが 40 万通りあるデータセットをスキャンすることです。私が使用したコードの一例を以下に示しますが、配列が 1 レコードを超えるとエラーが発生するようです。役立つヒントをいただければ幸いです。ありがとうございました。

# starting dataframe is df

lat1 = df.lat1.as_matrix()
long1 = df.long1.as_matrix()
lat2 = df.lat2.as_matrix()
long2 = df.df_long2.as_matrix()

from geopy.distance import vincenty
point1 = (lat1, long1)
point2 = (lat2, long2)
print(vincenty(point1, point2).miles)
4

3 に答える 3

6

編集:これは簡単なノートブックの例です

ポイントを含む DataFrame 列があり、それらすべての間の距離を計算したい場合の一般的なアプローチ (たとえば、別々の列がある場合は、最初にそれらを(lon, lat)タプルに結合します)。新しい列に名前を付けますcoords

import pandas as pd
import numpy as np
from geopy.distance import vincenty


# assumes your DataFrame is named df, and its lon and lat columns are named lon and lat. Adjust as needed.
df['coords'] = zip(df.lat, df.lon)
# first, let's create a square DataFrame (think of it as a matrix if you like)
square = pd.DataFrame(
    np.zeros(len(df) ** 2).reshape(len(df), len(df)),
    index=df.index, columns=df.index)

この関数は、入力列名を使用して DataFrame から「終了」座標を検索し、列を最初の引数として使用して、入力列の各行にdfgeopy 関数を適用します。これが機能するのは、関数が列方向に右から左に適用されるためです。vincenty()square.coords

def get_distance(col):
    end = df.ix[col.name]['coords']
    return df['coords'].apply(vincenty, args=(end,), ellipsoid='WGS-84')

これで、すべての距離を計算する準備が整いました。距離を取得するために使用するメソッドは、インデックス ラベル、行ラベル
を参照するため 、DataFrame( .T)を転置します。ただし、内部の適用関数 (上記を参照) は、取得した値を列に入力します。loc[]

distances = square.apply(get_distance, axis=1).T

値は ( IIRC ) キロメートル単位で返されるため、などを使用して、geopyこれらを使用したい単位に変換する必要がある場合があります。.meters.miles

次のようなものが機能するはずです。

def units(input_instance):
    return input_instance.meters

distances_meters = distances.applymap(units)

たとえば を使用して、距離行列にインデックスを付けることができるようになりましloc[row_index, column_index]た。上記をかなり簡単に適応させることができるはずです。に正しい値を確実に渡すためapplyに、関数内の呼び出しを調整する必要がある場合があります。pandas のドキュメントは、特に を使用して位置引数を渡す場合に役立つ場合があります (これを機能させるには、最新の pandas バージョンが必要です)。get_distancegreat_circleapplyargs

このコードはプロファイリングされておらず、おそらくもっと高速な方法がありますが、400k の距離計算ではかなり高速になるはずです。

ああ、また

(lon, lat)geopy が座標をまたはとして期待するかどうか思い出せません(lat, lon)。きっと後者です(笑)。

更新 2021 年 5 月現在の作業スクリプトは次のとおりです。

import geopy.distance
# geopy DOES use latlon configuration
df['latlon'] = list(zip(df['lat'], df['lon']))
square = pd.DataFrame(
    np.zeros((df.shape[0], df.shape[0])),
    index=df.index, columns=df.index
)

# replacing distance.vicenty with distance.distance
def get_distance(col):
    end = df.loc[col.name, 'latlon']
    return df['latlon'].apply(geopy.distance.distance,
                              args=(end,),
                              ellipsoid='WGS-84'
                             )

distances = square.apply(get_distance, axis=1).T
于 2016-04-18T15:45:38.110 に答える