如何分别计算不同维度的欧氏距离?

时间:2017-11-19 15:21:43

标签: matlab euclidean-distance pdist

我在使用pdist时遇到了一个问题,如果你能给我一些建议,那将是非常感谢的。 pdist(D)通常给出多维度的距离之和,但是,我想分别得到距离。例如,我有一个10 * 2矩阵的数据集S,我使用pdist(S(:,1))pdist(S(:,2))来分别获取距离,但是当数据有很多时,这似乎非常低效尺寸。有没有其他方法可以实现更高效的效果?提前谢谢!

2 个答案:

答案 0 :(得分:3)

假设您只想要点的各个维度之间的绝对差异,那么pdist是过度的。您可以使用以下简单功能

function d = pdist_1d(S)
    idx = nchoosek(1:size(S,1),2);
    d = abs(S(idx(:,1),:) - S(idx(:,2),:));
end

返回S中所有行对之间的绝对成对差异。

在这种情况下

dist = pdist_1d(S)

给出与

相同的结果
dist = cell2mat(arrayfun(@(dim)pdist(S(:,dim))',1:size(S,2),'UniformOutput',false));

答案 1 :(得分:1)

另一种选择,因为你只是简单地取坐标的绝对差异,就是使用bsxfun

>> D = randi(20, 10, 2)   % generate sample data
D =

   17   12
   14   10
    8    4
    7   11
   19   13
    2   18
   11   14
    5   19
   19   12
   20    8

从这里开始,我们置换数据,使坐标(列)延伸到第3维,第1个参数的第1维和第2个参数的第2维:

>> dist = bsxfun(@(x,y)abs(x-y), permute(D, [1 3 2]), permute(D, [3 1 2]))
dist =

ans(:,:,1) =

    0    3    9   10    2   15    6   12    2    3
    3    0    6    7    5   12    3    9    5    6
    9    6    0    1   11    6    3    3   11   12
   10    7    1    0   12    5    4    2   12   13
    2    5   11   12    0   17    8   14    0    1
   15   12    6    5   17    0    9    3   17   18
    6    3    3    4    8    9    0    6    8    9
   12    9    3    2   14    3    6    0   14   15
    2    5   11   12    0   17    8   14    0    1
    3    6   12   13    1   18    9   15    1    0

ans(:,:,2) =

    0    2    8    1    1    6    2    7    0    4
    2    0    6    1    3    8    4    9    2    2
    8    6    0    7    9   14   10   15    8    4
    1    1    7    0    2    7    3    8    1    3
    1    3    9    2    0    5    1    6    1    5
    6    8   14    7    5    0    4    1    6   10
    2    4   10    3    1    4    0    5    2    6
    7    9   15    8    6    1    5    0    7   11
    0    2    8    1    1    6    2    7    0    4
    4    2    4    3    5   10    6   11    4    0

这导致3-d对称矩阵

dist(p, q, d)

为您提供尺寸为p的点qd之间的距离

dist(p, q, d) == dist(q, p, d)

如果您想要所有(或多个)维度中pq之间的距离,则应使用squeeze将其放入向量中:

>> squeeze(dist(3, 5, :))
ans =

   11
    9

请注意,如果您使用的是MATLAB 2016b或更高版本(或Octave),则无需bsxfun即可创建相同的距离矩阵:

dist = abs(permute(D, [1 3 2]) - permute(D, [3 1 2]))

这种方法的缺点是它会创建完整的对称矩阵,因此您需要两次生成每个距离,这可能会成为内存问题。