Можно ли векторизовать расчет расстояния от источника до массива целей в pandas кадре данных? - PullRequest
1 голос
/ 27 февраля 2020

В настоящее время у меня есть pandas DataFrame, настроенный так:

ID, Source Coord, Target Coords

1, (35, -75), [(30, -72), (31, -71), ...]
2, (34, -74), [(50, -50), (45,-45), ...]

Исходными и целевыми координатами являются широта и долгота. У меня есть векторизованная функция для расчета расстояния от источника до некоторых целевых узлов:

from numba import njit
@njit
def haversine_nb(lat1, lon1, lat2, lon2):
    lon1, lat1, lon2, lat2 = np.radians(lon1), np.radians(lat1), np.radians(lon2), np.radians(lat2)
    dlon = lon2 - lon1
    dlat = lat2 - lat1
    a = np.sin(dlat/2.0)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2.0)**2
    return 3958.7613 * 2 * np.arcsin(np.sqrt(a))

def calculate_distance(source_loc, target_locs):
    tlat = np.array([t[0] for t in target_locs])
    tlon = np.array([t[1] for t in target_lcos])
    slat = np.full(tlat.shape, source_loc[0])
    slon = np.full(tlon.shape, source_loc[1])
    arr = haversine_nb(slat, slon, tlat,tlon)

Я хочу создать еще один столбец в кадре данных, который будет содержать список расстояний от источника до целевых координат для каждого Я БЫ. Примерно так:

ID, Source Coord, Target Coords, Distances(mi)

1, (35, -75), [(30, -72), (31, -71), ...], [5,1, ...]
2, (34, -74), [(50, -50), (45,-45), ...], [10, 2,...]

Я знаю, что могу использовать функцию .apply на Dataframe, но она очень медленная, так как DataFrame большой. Мне было интересно, если кто-нибудь знает, есть ли способ генерировать это новый столбец с использованием векторизации.

1 Ответ

3 голосов
/ 27 февраля 2020

Расширьте до аккуратного формата с сопоставлением «многие к одному» от источников к целям:

1, (35, -75), [(30, -72), (31, -71), ...]

Таким образом,

ID   Source     Target
1    (35, -75)  (30, -72)
1    (35, -75)  (31, -71)
1    (35, -75)  ...

Затем просто получите расстояния от ваших векторизованных столбцов между источником и цель. Если вы хотите вернуть его обратно в форму ID-centri c, сверните его обратно в списки.


@ ifly6, извинения за редактирование вашего поста, но он кажется наиболее эффективным и подходящим способом получить это информация по всему. Пожалуйста, отредактируйте, как считаете нужным.

df_ = df.explode('Target Coords')

lat1, lon1 = map(np.array, zip(*df_['Source Coord']))
lat2, lon2 = map(np.array, zip(*df_['Target Coords']))

haversine_nb(lat1, lon1, lat2, lon2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...