2017-11-19 19 views
0

pdistを使用して質問がありましたら、アドバイスをいただければ幸いです。 pdist(D)は、通常、複数次元の距離の合計を返しますが、距離を別々に取得したいと考えています。例えば、データセットSが10 * 2のマトリックスで、別に距離を得るためにpdist(S(:,1))pdist(S(:,2))を使用していますが、データに多数のディメンションがある場合は非常に非効率的です。これをより効率的にする方法がありますか?前もって感謝します!ユークリッド距離を別の次元で別々に計算する方法は?

答えて

3

ポイントの個々の次元の絶対差を求めたいと思うなら、pdistは過剰です。あなたは、次の簡単な関数S内の行のすべてのペア間の絶対ペアごとの差を返し

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

を使用することができます。この場合

dist = pdist_1d(S) 

dist = cell2mat(arrayfun(@(dim)pdist(S(:,dim))',1:size(S,2),'UniformOutput',false)); 
+0

@jodagありがとう、あなたのアプローチは非常に便利です。私が 'dist 'を得た後、' exp(sum(10. * dist。^ 2,2)) 'を計算したいのですが、あなたは何か提案がありますか? – zdeng

+0

私はあなたが書いたものよりも速い何かを見つけるのではないかと疑います。 – jodag

+0

または、おそらく 'bsxfun'が高速でしょうか? – zdeng

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次元:これは、3次元の対称行列になる

>> 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 

ここ

dist(p, q, d) 

あなたが0123の間の距離をしたい場合は、あなたに

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

を持つディメンションdの点pqの間の距離を与えますとすべてでq(または複数)の寸法、あなたはベクトルにそれを置くためにsqueezeを使用する必要があります。

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

    11 
    9 

メモMATLAB 2016B以降(またはオクターブ)を使用している場合は、同じ距離を作成できることbsxfunなしの行列は:

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

このアプローチの欠点は、それが潜在的にメモリの問題になる可能性がありますが、2回ずつ距離を生成しているので、完全な対称行列を、作成することです。

+0

ありがとうございます@ビーカー。これは非常に良い理想です。私は 'exp(-10 * dist(:、:、1)。^ 2 - 5 * dist(:、:、2)を計算するための方法があれば疑問です。 )効率的に。 – zdeng

関連する問題