Попарное расстояние различных элементов в пандах - PullRequest
0 голосов
/ 22 октября 2018

У меня есть датафрейм с некоторыми различными элементами, идентифицированными по идентификатору.Для каждого из них предусмотрены LAT, LON.Пример приведен ниже:

ID       LAT        LON

2426  0.351649  36.921941
2451  0.351666  36.921939
2457  0.351687  36.921966

Я хотел бы, чтобы словарь определялся кортежем (ID1, ID2) и расстоянием в качестве значения:

{(2426,2451):d1, (2426,2457):d2, (2451,2457):d3}

Теперь я вычисляюрасстояние между каждой парой с помощью следующего кода:

distances = {}
ids = to_network['ID'].values
for id_1 in ids:
    ids = np.delete(ids, np.where(ids == id_1), axis=0)
    for id_2 in ids:
        distances[(id_1,id_2)] = compute_distance_m(to_network.loc[(to_network['ID'] == id_1),'LAT'].values[0],to_network.loc[(to_network['ID'] == id_1),'LON'].values[0],to_network.loc[(to_network['ID'] == id_2),'LAT'].values[0],to_network.loc[(to_network['ID'] == id_2),'LON'].values[0])

# Result in m
def compute_distance_m(lat1,lon1,lat2,lon2):
    coords_1 = (lat1, lon1)
    coords_2 = (lat2, lon2)
    return geopy.distance.vincenty(coords_1, coords_2).km*1000

#returns
{(2426, 2451): 1.9917619328904765,
 (2426, 2457): 5.083739036769186,
 (2451, 2457): 3.7473346626876483}

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

1 Ответ

0 голосов
/ 22 октября 2018

С scipy и geopy

from geopy.distance import vincenty
from scipy import spatial
ary=spatial.distance.cdist(df[['LAT','LON']], df[['LAT','LON']], metric=lambda u, v: vincenty(u, v).kilometers)
disdf=pd.DataFrame(ary,columns=df.ID,index=df.ID)
disdf
Out[57]: 
ID        2426      2451      2457
ID                                
2426  0.000000  0.001893  0.005040
2451  0.001893  0.000000  0.003798
2457  0.005040  0.003798  0.000000

Обновление

idx = np.triu_indices(len(ary))
ary[idx] = np.nan
pd.DataFrame(ary,columns=df.ID,index=df.ID).stack().to_dict()
Out[67]: 
{(2451, 2426): 0.0018929013674396785,
 (2457, 2426): 0.005039829336784733,
 (2457, 2451): 0.0037980539470027124}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...