Расстояние до ближайшей точки в том же DF - PullRequest
1 голос
/ 03 февраля 2020

У меня есть df с идентификатором объекта, широтой и долготой. Я хотел бы создать два новых столбца: расстояние до ближайшей точки и идентификатор объекта ближайшей точки.

df[['OBJECT_ID','Lat','Long']].head()

    OBJECT_ID   Lat Long
0   33007002190000.0    47.326963   -103.079835
1   33007007900000.0    47.259770   -103.040797
2   33007008830000.0    47.296953   -103.099424
3   33007012130000.0    47.256700   -103.597082
4   33007013320000.0    46.996013   -103.452384

Как это можно сделать в Python с любой библиотекой? Также, если это помогает, мой DF содержит несколько тысяч строк.

1 Ответ

1 голос
/ 03 февраля 2020

Вы можете использовать для этого scipy's KDTree . Он отлично подходит для запроса пространственного расстояния.

С данными вашего примера вы можете сделать что-то вроде

import scipy

coordinates = df[["Lat", "Long"]]
# build kdtree
kdtree = scipy.spatial.cKDTree(coordinates)
# query the same tree with the same coordinates. NOTICE the k=2
distances, indexes = kdtree.query(coordinates, k=2)

# assign it to a new dataframe (NOTICE the index of 1)
new_df = df.assign(ClosestID=df["OBJECT_ID"][indexes[:,1]].array)
new_df = new_df.assign(ClosestDist=distances[:,1])

с результатом

>> new_df

OBJECT_ID   Lat Long    ClosestID   ClosestDist
0   33007002190000.0    47.326963   -103.079835 33007008830000.0    0.035838
1   33007007900000.0    47.259770   -103.040797 33007008830000.0    0.069424
2   33007008830000.0    47.296953   -103.099424 33007002190000.0    0.035838
3   33007012130000.0    47.256700   -103.597082 33007013320000.0    0.298153
4   33007013320000.0    46.996013   -103.452384 33007012130000.0    0.298153

Причина использования k=2 потому что ближайшее расстояние (при запросе с одинаковыми координатами) всегда будет одной и той же точкой. т.е.:

>> kdtree.query(coordinates, k=2)

# this is distance
(array([[0.        , 0.03583754],
        [0.        , 0.06942406],
        [0.        , 0.03583754],
        [0.        , 0.29815302],
        [0.        , 0.29815302]]), 
#        ^           ^
#        |           |
#     closest     second-closest

# this is indexes
 array([[0, 2],
        [1, 2],
        [2, 0],
        [3, 4],
        [4, 3]]))

Самая близкая точка к каждой точке - сама. Поэтому мы игнорируем первый элемент и используем index = 1 для извлечения второй ближайшей точки (т.е. ближайшей точки, отличной от самой себя).

...