Это решение реализует расстояние в numpy
, так как я думаю, что это хороший пример широковещания , что очень полезно знать, если вам нужно использовать массивы и матрицы.
По определению манхэттенского расстояния необходимо оценить сумму абсолютных значений разности между каждым столбцом. Однако первый столбец x
, x[:, 0]
имеет форму (4,), а первый столбец y
, y[:, 0]
имеет форму (2,), поэтому они несовместимы в смысле применениявычитание: свойство широковещания говорит, что каждая фигура сравнивается, начиная с конечных измерений, и два измерения совместимы, когда они равны или одно из них равно 1. К сожалению, ни одно из них не подходит для ваших столбцов.
ОднакоВы можете добавить новое измерение значения 1, используя np.newaxis
, поэтому
x[:, 0]
равно array([1, 2, 4, 5])
, но
x[:, 0, np.newaxis]
равно
array([[1],
[2],
[4],
[5]])
и его форма (4, 1). Теперь матрица формы (4, 1), вычтенная из массива формы 2, приводит к матрице формы (4, 2) с помощью радиовещательной обработки numpy
:
4 x 1
2
= 4 x 2
. Вы можетеполучите различия для каждого столбца:
first_column_difference = x[:, 0, np.newaxis] - y[:, 0]
second_column_difference = x[:, 1, np.newaxis] - y[:, 1]
и оцените сумму их абсолютных значений:
np.abs(first_column_difference) + np.abs(second_column_difference)
, что приведет к матрице (4, 2). Теперь вы хотите суммировать значения для каждой строки, чтобы у вас было 4 значения:
np.sum(np.abs(first_column_difference) + np.abs(second_column_difference), axis=1)
, что приводит к array([73, 69, 61, 57])
. Правило простое: параметр axis
исключит это измерение из результата, поэтому при использовании axis=1
для матрицы (4, 2) генерируется 4 значения - если вы используете axis=0
, то генерирует 2 значения.
Итак, это решит вашу проблему:
x = np.array([[1, 2], [2, 3], [4, 5], [5, 6]])
y = np.array([[11, 13], [12, 43]])
first_column_difference = x[:, 0, np.newaxis] - y[:, 0]
second_column_difference = x[:, 1, np.newaxis] - y[:, 1]
z = np.abs(first_column_difference) + np.abs(second_column_difference)
print(np.sum(z, axis=1))
Вы также можете пропустить промежуточные шаги для каждого столбца и оценить все сразу (это немного сложнее понять, поэтому я предпочитаюописанный выше метод для объяснения происходящего):
print(np.abs(x[:, np.newaxis] - y).sum(axis=(1, 2)))
Это общий случай для n-мерного манхэттенского расстояния: если x
равно (u, n) и y
равно (v, n), он генерирует u строки, передавая (u, 1, n)
на (v, n)
= (u, v, n)
, затем применяя sum
, чтобы исключить вторую и третью оси.