У меня есть два коррелированных набора данных Nx3 (один из них - xyz, другой - нормальный вектор для этих точек). У меня есть точка в моем первом наборе данных, и теперь я хочу найти совпадающую строку во втором наборе данных. Каков наилучший способ сделать это? Я думал распечатать номер строки, но не уверен, что именно этот код должен сделать?Поиск подходящей строки в двух отдельных наборах данных в matlab
ответ
Учитывая, что у вас есть точка в вашем одном наборе данных размером 1 x 3, вы можете сделать это двумя способами.
Метод # 1 - Использование knnsearch
Самый простой способ будет использовать knnsearch
из Statistics Toolbox.
knnsearch
означает K-Nearest Поиск по соседству. Учитывая входную точку запроса, knnsearch
находит k
ближайшими точками к вашему набору данных с учетом входной точки запроса. В вашем случае, k=1
. Кроме того, метрика расстояния является евклидовым расстоянием, но, видя, как ваши точки находятся в трехмерном картезианском пространстве, я не вижу в этом проблемы.
Таким образом, предполагая, что ваши xyz
точки сохраняются в X
и точка запроса (нормальный вектор) в y
, просто сделать это:
IDX = knnsearch(X, y);
Вышеприведенные настройки по умолчанию для k=1
. Если вы хотите больше, чем один пункт вернулся, вы могли бы сделать это:
IDX = knnsearch(X, y, 'K', n);
n
этим количество очков, которое вы хотите возвратившиеся или n
ближайших точек, данные запроса y
. IDX
содержит индекс которого в X
ближайший к y
. Я также хотел бы отметить, что X
устроен таким образом, что каждая строка является точкой, и каждый столбец является переменной.
Поэтому ближайшая точка с использованием IDX
будет:
closest_point = X(IDX,:);
Способ № 2 - Использование bsxfun
Если вы не имеете Statistics Toolbox, вы можете очень легко достичь того же эффекта, используя bsxfun
. Имейте в виде, что код, который я буду писать это только для возвращения ближайшей точки, или k=1
:
dists = sqrt(sum(bsxfun(@minus, X, y).^2, 2));
[~,IDX] = min(dists);
bsxfun
вызова первым определяет покомпонентное расстояние между y
и каждой точкой X
. Как только мы это сделаем, мы квадратизируем каждый компонент, складываем все компоненты вместе, а затем берем квадратный корень. Это, по существу, находит евклидово расстояние с y
и все точки в X
. Это дает нам N
расстояния, где N
- общее количество точек в наборе данных. Затем мы найдем минимальное расстояние с min
и определим индекс, где находится ближайшая точка совпадения, которая соответствует ближайшей точке между y
и набором данных.
Если вы хотите увеличить это до более чем одной точки, вы должны отсортировать расстояния в порядке возрастания, а затем получить такое количество точек с наименьшими расстояниями. Помните, что меньшие евклидовы расстояния означают, что точки схожи, поэтому мы сортируем в порядке возрастания. Что-то вроде этого:
dists = sqrt(sum(bsxfun(@minus, X, y).^2, 2));
[~,ind] = sort(dists);
IDX = ind(1:n);
Просто небольшой шаг вверх от того, что у нас было до этого. Вместо того, чтобы использовать min
, вы должны использовать sort
и получить второй вывод sort
для определения местоположения минимальных расстояний. Затем мы индексировали бы ind
, чтобы получить самые близкие индексы n
и, наконец, проиндексируем их в X
, чтобы получить наши фактические баллы.
Вы бы снова делать то же самое, чтобы получить фактические точки, которые находятся ближе всего:
closest_point = X(IDX,:);
Некоторые Bonus Материал
Если вы хотите узнать больше о том, как K-ближайший сосед работает, Я рекомендую вам прочитать мой пост об этом здесь:
Finding K-nearest neighbors and its implementation
удачи!