如何在向量中找到最接近(最近)的值到另一个向量?

时间:2016-06-12 10:23:28

标签: arrays matlab vector distance

我有两个相同大小的矢量,例如

A=[2.29 2.56 2.77 2.90 2.05] and
B=[2.34 2.62 2.67 2.44 2.52].

我有兴趣在两个相同大小的矢量A和A中找到最接近的值(几乎相等)。 B,即在A中的所有元素中,哪个值最接近B的任何元素?解决方案也应该可扩展到任意数量(相同大小)的向量。能够用一组相同大小的矢量A,B和C找到最接近的值的装置。两个结果值可以来自两个向量中的任何一个。

为清楚起见,我不想在单个向量中找到最接近的值。以上示例的答案是值2.56和2.52。

3 个答案:

答案 0 :(得分:4)

这适用于通用数字 可能不同长度的向量:

vectors = {[2.29 2.56 2.77 2.90 2.05] [2.34 2.62 2.67 2.44 2.52] [1 2 3 4]}; 
    % Cell array of data vectors; 3 in this example
s = cellfun(@numel, vectors); % Get vector lengths
v = [vectors{:}]; % Concatenate all vectors into a vector
D = abs(bsxfun(@minus, v, v.')); % Compute distances. This gives a matrix.
    % Distances within the same vector will have to be discarded. This will be
    % done by replacing those values with NaN, in blocks
bb = arrayfun(@(x) NaN(x), s, 'uniformoutput', false); % Cell array of blocks
B = blkdiag(bb{:}); % NaN mask with those blocks
[~, ind] = min(D(:) + B(:)); % Add that mask. Get arg min in linear index
[ii, jj] = ind2sub(size(D), ind); % Convert to row and column indices
result = v([ii jj]); % Index into concatenated vector

答案 1 :(得分:3)

作为使用bsxfun的两个向量的起点:

%// data
A = [2.29 2.56 2.77 2.90 2.05]
B = [2.34 2.62 2.67 2.44 2.52]

%// distance matrix 
dist = abs(bsxfun(@minus,A(:),B(:).'));

%// find row and col indices of minimum
[~,idx] = min(dist(:))
[ii,jj] = ind2sub( [numel(A), numel(B)], idx)

%// output 
a = A(ii)
b = B(jj)

现在你可以将它放入循环等。

顺便说一下:

dist = abs(bsxfun(@minus,A(:),B(:).'));

等同于更明显的:

dist = pdist2( A(:), B(:) )

但我宁愿选择第一个避免开销的解决方案。

最后是多向量的完全向量化方法:

%// data
data{1} = [2.29 2.56 2.77 2.90 2.05];
data{2} = [2.34 2.62 2.67 2.44 2.52];
data{3} = [2.34 2.62 2.67 2.44 2.52].*2;
data{4} = [2.34 2.62 2.67 2.44 2.52].*4;
%// length of each vector
N = 5;

%// create Filter for distance matrix
nans(1:numel(data)) = {NaN(N)};
mask = blkdiag(nans{:}) + 1; 

%// create new input for bsxfun
X = [data{:}];

%// filtered distance matrix 
dist = mask.*abs(bsxfun(@minus,X(:),X(:).'));

%// find row and col indices of minimum
[~,idx] = min(dist(:))
[ii,jj] = ind2sub( size(dist), idx)

%// output 
a = X(ii)
b = X(jj)

答案 2 :(得分:1)

就像长评论一样,如果您可以访问统计和机器学习工具箱,那么您可以使用K-Nearest Neighbors函数,这些函数具有以下优点:

  1. 处理不同长度的数组,例如当尺寸(A)= [ M ,1]和尺寸(B)= [ N ,1] < / p>

  2. 处理二维数组,例如当尺寸(A)= [M, d ]和尺寸(B)= [N, d ] <时/ p>

  3. 处理不同距离类型,例如:Euclidean,City block,Chebychev等等,甚至您拥有自定义距离

    < / LI>
  4. 将KDTree算法用于一些特殊情况,可以带来很好的表现。

  5. 虽然在你的情况下回答来自&#34; Luis Mendo&#34;看起来相当不错,但它不能扩展为K-Nearest Neighbors从工具箱提供的功能。

    更新:示例代码

    % A and B could have any Dimension, just same number of columns (signal Dimension)
    A = rand(1000,4);
    B = rand(500,4);
    
    % Use any distance you like, some of them are not supported for KDTreeSearcher,
    % and you should use ExhaustiveSearcher
    myKnnModel= KDTreeSearcher(A, 'Distance', 'minkowski');
    
    % you can ask for many (K) Nearest Neighbors and you always have access to it for later uses
    [Idx, D] = knnsearch(myKnnModel, B, 'K',2);
    
    % and this is answer to your special case
    [~, idxA] = min(D(:, 1))
    idxB = Idx(idxA)