Pythonic (и наиболее производительный) способ генерировать расстояние между всеми точками, сохраняя meta_data? - PullRequest
0 голосов
/ 27 октября 2018

У меня есть фрейм данных, который содержит координаты x и y и идентификатор, который выглядит следующим образом:

df = pd.DataFrame(np.random.randint(0,100,size=(26, 2)), columns=list('XY'))
df['id'] = list('abcdefghijklmnopqrstuvwxyz')

Как мне найти линейное расстояние между одной областью и всеми другими областями без использования питонаиметь набор вложенных циклов, сохраняя идентификаторы области OD?

Вывод должен давать тот же результат, что и:

import math
def get_distance(start, end):
    dist = math.hypot(end[0]-start[0], end[1]-start[1])
    return dist

data = []

for index, row in df.iterrows():
    start = [row['X'], row['Y']]
    start_region = row['id']

    for other_index, other_row in df.iterrows():
        end = [other_row['X'], other_row['Y']]
        end_rengion = other_row['id']
        distance = get_distance(start, end)

        entry = dict(
            start_region = start_region,
            end_rengion = end_rengion,
            distance = distance
        )

        data.append(entry)

pd.DataFrame(data)

1 Ответ

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

Вы можете использовать scipy.spatial.distance.cdist , чтобы сделать это. Это функция scipy, написанная на c, поэтому она намного быстрее по сравнению с вложенными циклами python.

import pandas as pd
import numpy as np
from scipy.spatial import distance
import itertools

df = pd.DataFrame(np.random.randint(0,100,size=(26, 2)), columns=list('XY'))
ids = list('abcdefghijklmnopqrstuvwxyz')
df['id'] = ids

# get the points
points = df[["X", "Y"] ].values

# calculate distance of each point from every other point, row i contains contains distances for point i. distances[i, j] contains distance of point i from point j.
distances = distance.cdist(points, points, "euclidean")
distances = distances.flatten()

# get the start and end points
cartesian = list(itertools.product(ids, ids))

data = dict(
            start_region = [x[0] for x in cartesian],
            end_rengion = [x[1] for x in cartesian],
            distance = distances
        )
print(pd.DataFrame(data))

Редактировать в соответствии с комментарием ОП: Вы можете предоставить пользовательскую функцию для cdist, поэтому изменение евклидова расстояния до точек Google API не должно быть слишком сложным.

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