Вычислить попарно элемент двух одномерных массивов

Вот моя проблема:

скажем, мои два массива:

import numpy as np
first = np.array(["hello", "hello", "hellllo"])
second = np.array(["hlo", "halo", "alle"])

Теперь я хочу получить матрицу расстояний между каждым элементом двух массивов

так, например, моя функция расстояния:

def diff_len(string1, string2):
    return abs(len(string1) - len(string2))

Итак, я хотел бы получить матрицу:

        hello       hello    hellllo

hlo    result1     result2   result3
halo   result4     result5   result6
alle   result7     result8   result9

Итак, что я сделал, так это вычислил строку за строкой, используя функцию векторизации Numpy:

vectorize_dist = np.vectorize(diff_len)

first = np.array(["hello", "hello", "hellllo"])
second = np.array(["hlo", "halo", "alle"])

vectorize_dist(first , "hlo")
vectorize_dist(first , "halo")
vectorize_dist(first , "alle")

matrix = np.array([vectorize_dist(first , "hlo"), vectorize_dist(first , "halo"), vectorize_dist(first , "alle")])
matrix

array([[2, 2, 4],
       [1, 1, 3],
       [1, 1, 3]])

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


person Enzo Ramirez C.    schedule 28.10.2020    source источник


Ответы (1)


Вы можете использовать SciPy для что:

import numpy as np
from scipy.spatial.distance import cdist

def diff_len(string1, string2):
    return abs(len(string1) - len(string2))

first = np.array(["hello", "hello", "hellllo"])
second = np.array(["hlo", "halo", "alle"])
d = cdist(first[:, np.newaxis], second[:, np.newaxis], lambda a, b: diff_len(a[0], b[0]))
print(d.T)
# [[2. 2. 4.]
#  [1. 1. 3.]
#  [1. 1. 3.]]

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

person jdehesa    schedule 28.10.2020
comment
У меня есть несколько матриц расстояний для вычисления, могу ли я использовать многопроцессорность, чтобы использовать все мои ядра для ускорения полных вычислений? - person Enzo Ramirez C.; 04.11.2020
comment
@EnzoRamirezC. Да, это должно быть возможно сделать, например. с многопроцессорным пулом, хотя он имеет накладные расходы, поэтому, сможете ли вы получить значительный прирост производительности, будет зависеть от размера проблемы. Я также не уверен, что что-то вроде cdist уже использует несколько ядер или нет. Вы также можете изучить параллельную Numba (в этом случае без cdist, просто используя циклы), хотя для эффективности ваш код должен быть изначально компилируемым с помощью jit. - person jdehesa; 04.11.2020