#python #numpy #scikit-learn
Вопрос:
У меня есть два больших numpy
массива, для которых я хочу рассчитать евклидово расстояние, используя sklearn
. Следующий MRE достигает того, что я хочу в конечном результате, но, поскольку мое использование RL велико, мне действительно нужно векторизованное решение, а не использование for
цикла.
import numpy as np
from sklearn.metrics.pairwise import euclidean_distances
n = 3
sample_size = 5
X = np.random.randint(0, 10, size=(sample_size, n))
Y = np.random.randint(0, 10, size=(sample_size, n))
lst = []
for f in range(0, sample_size):
ed = euclidean_distances([X[f]], [Y[f]])
lst.append(ed[0][0])
print(lst)
Комментарии:
1. Вы указали, что хотите использовать
sklearn
для вычисления расстояний. Это действительно необходимо? Если это так, то я думаю, что вы застряли с тем, что они вам дали. Если нет, то непонятно, в чем проблема будет заключаться в написании вашего собственного, как вы хотите. Евклидово расстояние не является сложной функцией.2. Возможно, я неправильно истолковываю то, чего вы пытаетесь достичь, но
euclidean_distances(X, Y).diagonal()
не делаете то, что вы хотите? Если нет, не могли бы вы объяснить, чем это отличается от того, чего вы хотите?3.
np.sqrt(((X - Y)**2).sum(1))
?4. @Brick да, я знаю, это для онлайн-класса, и поэтому я предполагаю, что мы будем опираться на его сложность.
5. @Брайан: это работает! Можете ли вы отправить сообщение в качестве ответа, и я приму его?
Ответ №1:
euclidean_distances
вычисляет расстояние для каждой комбинации точек X,Y; это увеличит объем памяти и совершенно не нужно, если вам просто нужно расстояние между каждой соответствующей строкой. Sklearn включает в себя другую функцию, paired_distances
которая делает то, что вы хотите:
from sklearn.metrics.pairwise import paired_distances
d = paired_distances(X,Y)
# array([5.83095189, 9.94987437, 7.34846923, 5.47722558, 4. ])
Если вам нужны полные попарные расстояния, вы можете получить тот же результат по диагонали (как указано в комментариях).:
d = euclidean_distances(X,Y).diagonal()
Наконец: массивы относятся к типу numpy, поэтому полезно знать сам api numpy (prob. то, что склирн называет «под капотом»). Вот два примера:
d = np.linalg.norm(X-Y, axis=1)
d = np.sqrt(np.sum((X-Y)**2, axis=1))