在3D中查找随机最近的邻居

时间:2019-07-19 13:10:25

标签: python geopandas

在给定 750 人的名字和GPS位置(纬度,经度和海拔)时,我正在尝试实现Python代码,以查找随机选择的个人的10个最接近的邻居的名字。 / p>

import random
    #random = rand.sample(range(0,750), 10)
    coords = [(random.random()*2.0, random.random()*2.0, random.random()*2.0) for _ in range(750)]

3 个答案:

答案 0 :(得分:0)

您不能仅使用距离公式来计算给定x,y,z的两点之间的距离,其中d = sqrt((x2-x1)^ 2 +(y2-y1)^ 2 +(z2- z1)^ 2)以获取随机选择的人与所有其他元素之间的距离。只需计算每个人到随机人的距离,然后只存储十个最低值

答案 1 :(得分:0)

您可以使用sklearn中出色的BallTree:

import numpy as np
from sklearn.neighbors import BallTree

coords = np.random.random((750, 3)) * 2
tree = BallTree(coords)
random_person = np.random.choice(np.arange(750))
closest_people = tree.query(coords[None, random_person], k=10)[1]

答案 2 :(得分:0)

要执行此操作,您应该在球坐标系中进行操作,或者可以转换为笛卡尔坐标系。在笛卡尔坐标系下进行工作的假设是,直接距离而不是很大的椭圆弧是您测量距离的方式。

import numpy as np
from sklearn.neighbors import DistanceMetric

R = 6371 # approximate radius of earth in km

# coordinates in (lat,lon,elv) in units of (rad,rad,km)
coords = np.random.random((750, 3)) * 2
cart_coords = np.array([((R+coord[2]) * np.cos(coord[0]) * np.cos(coord[1]),
                         (R+coord[2]) * np.cos(coord[0]) * np.sin(coord[1]),
                         (R+coord[2]) *np.sin(coord[0])) for coord in coords])

# calculate distances between points
dist = DistanceMetric.get_metric('euclidean')
dist_vals = dist.pairwise(cart_coords)

# pick a random person
random_person = np.random.choice(np.arange(750))
top_ten = np.where(dist_vals[random_person] < sorted(dist_vals[random_person])[11])[0]
# remove self from list
top_ten = top_ten[top_ten!=random_person]

print(top_ten)

如果您希望忽略海拔高度并使用Havesine公式,可以查看此帖子Vectorizing Haversine distance calculation in Python

地球是一个椭圆形,极地和赤道半径之间相差约21公里。如果您真的想更深入,可以研究大地测量学。 astropy是解决这类问题https://docs.astropy.org/en/stable/api/astropy.coordinates.spherical_to_cartesian.html

的好方法