在Python中计算*多个*地理坐标集之间的距离

Col*_*lin 6 python numpy distance geopy pandas

我正在努力计算组经纬度坐标之间的距离。简而言之,我发现了很多使用数学或geopy的教程。当我只想查找一组坐标(或两个唯一位置)之间的距离时,这些教程非常有用。但是,我的目标是扫描具有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)
Run Code Online (Sandbox Code Playgroud)

urs*_*rei 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)
Run Code Online (Sandbox Code Playgroud)

此函数df使用输入列名称从DataFrame 中查找我们的“结束”坐标,然后将 geopyvincenty()函数应用于输入列中的每一行,使用该square.coords列作为第一个参数。这是有效的,因为该函数是从右到左按列应用的。

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

现在我们已准备好计算所有距离。
我们正在转置 DataFrame ( .T),因为loc[]我们将用于检索距离的方法是指索引标签、行标签。然而,我们的内部应用函数(见上文)用检索到的值填充一列

distances = square.apply(get_distance, axis=1).T
Run Code Online (Sandbox Code Playgroud)

你的geopy价值是(IIRC)在返回公里,所以你可能需要将这些转换为任何单位你想用用.meters.miles等等。

像下面这样的东西应该工作:

def units(input_instance):
    return input_instance.meters

distances_meters = distances.applymap(units)
Run Code Online (Sandbox Code Playgroud)

您现在可以使用例如索引到您的距离矩阵loc[row_index, column_index]。您应该能够很容易地适应上述内容。您可能需要调整函数apply中的get_distance调用以确保将正确的值传递给great_circle. Pandasapply文档可能很有用,特别是在使用传递位置参数方面args(您需要一个最新的 Pandas 版本才能工作)。

这段代码还没有被分析,可能有更快的方法来做到这一点,但对于 400k 距离计算应该相当快。

哦还有

我不记得 geopy 是否期望坐标为(lon, lat)(lat, lon)。我敢打赌是后者(叹气)。

更新 这是截至 2021 年 5 月的工作脚本。

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)
Run Code Online (Sandbox Code Playgroud)