Как рассчитать расстояние хаварсины между текущей и предыдущей строками? - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть df, который выглядит следующим образом, где я сгруппирован по id

 id     lat          lon
 1       NaN         NaN
 1       40.121      23.749
 1      -56.154     -39.572
 1       21.908      17.537
 1       31.221     -36.186
 1      -56.655      0.016
 2       NaN         NaN
 2      -36.438      14.874
 2      -21.422      81.271
 2       43.961     -95.551
 3       NaN         NaN
 3       79.821     -56.781

Используя функцию haversine, я бы хотел вычислить расстояние от текущей строки до предыдущей строки.Таким образом, первая запись нового столбца будет рассчитываться с использованием

lat 1 = 40.121

lon 1 = 23.749

lat 2 = -56.154

долг 2 = -39,572

1 Ответ

0 голосов
/ 20 февраля 2019

Адаптировано с этого ответа.Связанный ответ показывает, как вычислить расстояние между каждой строкой и некоторое фиксированное значение для долготы / широты - моя адаптация позволяет работать в вашем случае.

Во-первых, получите все необходимые значения в одной строке, используя shift:

df['lon2'] = df['lon'].shift(-1)
df['lat2'] = df['lat'].shift(-1)

Предоставление:

    id     lat     lon    lat2    lon2
0    1     NaN     NaN  40.121  23.749
1    1  40.121  23.749 -56.154 -39.572
2    1 -56.154 -39.572  21.908  17.537
3    1  21.908  17.537  31.221 -36.186
4    1  31.221 -36.186 -56.655   0.016
5    1 -56.655   0.016     NaN     NaN
6    2     NaN     NaN -36.438  14.874
7    2 -36.438  14.874 -21.422  81.271
8    2 -21.422  81.271  43.961 -95.551
9    2  43.961 -95.551     NaN     NaN
10   3     NaN     NaN  79.821 -56.781
11   3  79.821 -56.781     NaN     NaN

Затем определите функцию для расчета расстояния:

from numpy import cos, sin, arcsin, sqrt
from math import radians

def haversine(row):
    lon1 = row['lon']
    lat1 = row['lat']
    lon2 = row['lon2']
    lat2 = row['lat2']
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * arcsin(sqrt(a)) 
    km = 6367 * c
    return km

и примените ее к вашемуданные с использованием apply:

df['distance'] = df.apply(haversine, axis=1)

Предоставление:

    id     lat     lon    lat2    lon2      distance
0    1     NaN     NaN  40.121  23.749           NaN
1    1  40.121  23.749 -56.154 -39.572  12237.017692
2    1 -56.154 -39.572  21.908  17.537  10187.684397
3    1  21.908  17.537  31.221 -36.186   5387.540299
4    1  31.221 -36.186 -56.655   0.016  10343.267833
5    1 -56.655   0.016     NaN     NaN           NaN
6    2     NaN     NaN -36.438  14.874           NaN
7    2 -36.438  14.874 -21.422  81.271   6543.302199
8    2 -21.422  81.271  43.961 -95.551  17480.809345
9    2  43.961 -95.551     NaN     NaN           NaN
10   3     NaN     NaN  79.821 -56.781           NaN
11   3  79.821 -56.781     NaN     NaN           NaN

Как я полагаю, показывает результаты, которые вы ищете (я протестировал первый и егокажется правильным).

Если хотите, вы можете избавиться от двух вторичных столбцов широты / долготы после завершения вычислений:

df.drop(['lat2', 'lon2'], axis=1, inplace=True)

Я должен отметить, что это решение будетне даст вам максимально быстрых расчетов.См. Вторую половину ответа, который я связал, для изучения того, как это можно улучшить, если производительность является главным приоритетом, хотя ее необходимо адаптировать.

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