Поэлементное сравнение двух массивов без циклов for в Numpy

У меня есть один большой массив, называемый набором данных в Numpy размеров (700, 28, 28, 3). Предположим, что эта матрица похожа на приведенную ниже:

>>> dataset=np.random.rand(5600,28,28,3)
>>> dataset.shape
(5600, 28, 28, 3)

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

>>> query=np.random.rand(28,28,3)
>>> query.shape
(28, 28, 3)

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

Проблема в том, что я не хочу создавать цикл for в Python для вычисления MSE один за другим, сохранять MSE в другом массиве, а затем получать позицию наименьшего MSE, когда цикл заканчивается. У меня уже есть два цикла for перед этим сравнением, и поэтому я хотел бы сделать его максимально эффективным и быстрым. Можно ли решить такую ​​проблему без большого цикла for?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
717
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете создать функцию сканера, которая сканирует набор данных с помощью map, а затем извлекает минимальное местоположение MSE из полученной карты:

MSE_scanner = lambda A : ((query-A)**2).mean() # create the MSE comparison function
MSE_array = list(map(MSE_scanner, dataset)) # array of MSEs relevant to query
MSE_minimum = min(MSE_array) # extract the minimum MSE which should the one matched
query_location = MSE_array.index(MSE_minimum) # extract the location of the minimum MSE

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

AGawish 10.12.2020 12:50

Возможно, вы правы в том, что цикл for наиболее эффективен. Это может быть быстрее, чем три ответа, опубликованные до сих пор (включая мой), потому что внутри (под капотом) все эти ответы выполняют несколько проходов (обходов) через длинную последовательность (по крайней мере, один обход для вычисления SE или MSE или евклидова расстояние. Затем, по крайней мере, еще один проход, чтобы найти минимум из них.) С помощью цикла for за один проход вы можете вычислить SE, MSE или евклидово расстояние, а также следить за «бегущим минимумом». конце этого одного прохода, вы можете иметь позицию минимума.

fountainhead 10.12.2020 13:27

Вы можете сделать это:

se = (dataset-query)**2                            # Squared error - shape (L,28,28,3)
sum_of_se = np.sum(se.reshape(-1,28*28*3), axis=1) # Sum of squared error - shape (L,)
print (np.argmin(sum_of_se))                       # Position of minimum within sum_of_se

Для этого вы можете использовать cdist с квадратом евклидова расстояния:

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

dataset = np.random.rand(5600, 28, 28, 3)
query = np.random.rand(28, 28, 3)

res = cdist(query.reshape((1, -1)), dataset.reshape((5600, -1)), 'seuclidean')
print(np.argmin(res))

Другие вопросы по теме

Могу ли я использовать boost::copy_range для результата boost::adaptors::transformed поверх std::array, чтобы получить другой std::array?
Изменение состояния одной переменной также изменяет другую переменную
Как извлечь некоторые определенные строки массива numpy
Получить массив из json flutter
Как автоматически создать список экземпляров подкласса, чтобы иметь возможность вызывать метод «выполнить» для этих «скриптов» при запуске приложения?
Как проверить условие, если слово, введенное пользователем, присутствует в массиве, назначенном переменной
Удалить те же объекты из массива, что и другой массив объектов
Как я могу использовать функцию переключения с NodeList/Array для переключения темного режима во всех разделах с одним и тем же классом?
Получение отдельных значений из ArrayList<Integer>
Преобразование целочисленного ввода в цифру с использованием массива в C