Я бы написал функцию для вычисления расстояния. Я уверен, что есть более быстрый и эффективный способ написать это (понимание списков, агрегирование и т. Д. c.), Но удобочитаемость имеет значение, верно? :)
import numpy as np
def calculate_distance(fixed_arr, var_arr, penalty):
s_sum = 0.0
counter = 0
for num_1, num_2 in zip(fixed_arr, var_arr):
if np.isnan(num_1) or np.isnan(num_2):
counter += 1
else:
s_sum += (num_1 - num_2) ** 2
return np.sqrt(s_sum) + penalty * counter, counter
array1 = np.array([1, 2, 3, np.NaN, 5, 6])
array2 = np.array(
[
[3, 4, 9, 3, 4, 8],
[3, 4, np.NaN, 3, 4, 8],
[np.NaN, 9, np.NaN, 3, 4, 8],
[np.NaN, np.NaN, np.NaN, np.NaN, np.NaN, np.NaN],
]
)
dist = np.zeros(len(array2))
minus = 10
for index, arr in enumerate(array2):
dist[index], _ = calculate_distance(array1, arr, minus)
print(dist)
Вы должны очень внимательно подумать о значении переменной минус . Действительно ли полезно добавлять случайное значение?
Как предположил @Nathan, можно легко реализовать более эффективное использование ресурсов.
fixed_arr = array1
penalty = minus
dist = [
(
lambda indices=(np.isnan(fixed_arr) + np.isnan(var_arr)): np.linalg.norm(
fixed_arr[~indices] - var_arr[~indices]
)
+ (indices == True).sum() * penalty
)()
for var_arr in array2
]
print(dist)
Однако я бы попытался реализовать что-то подобное, только если бы мне было необходимо (если это узкое место). Во всех остальных случаях я был бы счастлив пожертвовать некоторыми ресурсами, чтобы получить некоторую читаемость и расширяемость.