Расчет манхэттенское расстояние используя Numpy
Подскажите, как можно модифицировать код, для расчета манхэттенского расстояния, что бы избавиться от цикла то есть использовать для расчета только библиотеку Numpy.
import numpy as np
train = np.random.randint(0, 255, (1000, 10))
test = np.random.randint(0, 255, (100, 10))
num_train = train.shape[0]
num_test = test.shape[0]
dists = np.zeros((num_test, num_train), np.float32)
for i_test in range(num_test):
dists[i_test] = np.linalg.norm(test[i_test] - train, ord=1, axis=1)
Ответы (1 шт):
Автор решения: Stanislav Volodarskiy
→ Ссылка
То что вам нужно - вычислить декартово произведение train и test, получить разности в виде векторов, перевести разницы в расстояния. Небольшое демо:
train = np.array([[1, 1], [2, 2], [3, 3]])
test = np.array([[1, 1], [2, 2]])
# train = [[1 1] [2 2] [3 3]]
# test = [[1 1] [2 2]]
a = np.repeat(train[np.newaxis, :, :], test.shape[0], axis=0)
# каждая строка нового массива - копия train
# a = [
# [[1 1] [2 2] [3 3]]
# [[1 1] [2 2] [3 3]]
# ]
b = np.repeat(test[:, np.newaxis, :], train.shape[0], axis=1)
# каждый столбец нового массива - копия test
# b = [
# [[1 1] [1 1] [1 1]]
# [[2 2] [2 2] [2 2]]
# ]
c = a - b
# попарные разницы векторов из train и test
# c = [
# [[ 0 0] [ 1 1] [ 2 2]]
# [[-1 -1] [ 0 0] [ 1 1]]
# ]
dists = np.linalg.norm(с, axis=2, ord=1)
# заменяем разницы на манхэтенновские нормы
# dists = [
# [0. 2. 4.]
# [2. 0. 2.]
# ]
Рабочий пример:
import numpy as np
train = np.random.randint(0, 255, (1000, 10))
test = np.random.randint(0, 255, (100, 10))
a = np.repeat(train[np.newaxis, : , :], test .shape[0], axis=0)
b = np.repeat(test [: , np.newaxis, :], train.shape[0], axis=1)
dists = np.linalg.norm(a - b, axis=2, ord=1)
print(dists.shape)
print(dists)