2017-05-25 72 views
2

所以我有兩個非常長的矩陣。如果兩個值如果兩列匹配兩個值,則新列中的值Matlab

First_Matrix:下面的樣品被給予

A = [... 
1 1 1; 
1 1 2; 
1 1 3; 
1 2 1; 
1 2 2; 
1 2 3; 
1 3 1; 
1 3 2; 
1 3 3]; 

第二矩陣

B = [... 
1 1 916; 
1 2 653; 
1 3 114]; 

而且我想一個三分之二矩陣,將所述第一矩陣與第二矩陣的第三列結合,基於2個矩陣匹配(相同)的前兩列中的值。

所以Ouput_Matrix:

C = [... 
1 1 1 916; 
1 1 2 916; 
1 1 3 916; 
1 2 1 653; 
1 2 2 653; 
1 2 3 653; 
1 3 1 114; 
1 3 2 114; 
1 3 3 11]; 

什麼是做到這一點的最好方法是什麼?

在此先感謝

+0

什麼是你的方法?首先提出幾個問題比較容易,在你的問題中對它們進行描述,以便我們可以告訴你哪一個更好,或者另一個更好。在我看來,如果你着急的話,兩個'for'循環會很好地完成這項工作。 –

+0

我假設'C'中最後一個'11'應該是'114',對嗎? –

回答

4

使用的ismember第二輸出與'rows'選項來獲得匹配的索引,從中你可以輕鬆地構建結果:

[~, ind] = ismember(A(:, [1 2]), B(:, [1 2]), 'rows'); 
C = [A B(ind, 3)]; 
+0

我想你的意思是'C = [A B(ind,3)];'。但這是一個非常優雅的解決方案! –

+0

@lmoes謝謝,糾正! –

+0

我不知何故忽略了你的答案。對不起,它真的很棒。非常優雅和快速。非常感謝,你們倆! – Rogier

1

for循環是不漂亮,可能你慢下來,如果B是很長。但我不認爲有可能避免(編輯:看起來是這樣)。

A = [1 1 1 
1 1 2 
1 1 3 
1 2 1 
1 2 2 
1 2 3 
1 3 1 
1 3 2 
1 3 3]; 

B = [1 1 916 
1 2 653 
1 3 114]; 

C = [A zeros(size(A,1),1)]; 

for i = 1:size(B,1) 
    C(all(B(i,1:2)==A(:,1:2),2),4) = B(i,3); 
end 

C = 
1  1  1 916 
1  1  2 916 
1  1  3 916 
1  2  1 653 
1  2  2 653 
1  2  3 653 
1  3  1 114 
1  3  2 114 
1  3  3 114 
+0

你爲什麼認爲'for'循環不漂亮? –

+1

順便說一句,你可以'all(B(idx,1:2)== A(:,1:2),2)'而不是'all'確實需要額外的參數來指示維度。 –

+1

也許我對循環有些過敏,但我儘量避免它們像瘟疫一樣,因爲它們往往是瓶頸,通常可以通過智能矩陣索引來避免。關於'all()'的小費Thx! –

0

它可以達到你想要什麼,而沒有for循環,但它可能不是最優化的實現:

n = size(B, 1); % number of rows in B 
B_(1, :, :) = B'; % convert to 3D matrix to be able to use elementwise comparision 
x = squeeze(all(bsxfun(@eq, A(:, 1:2), B_(1, 1:2,:)), 2)); % x(i, j) == 1 if row A(i, :) matches B(j, :) 
index = x * (1:n)'; % row B(index(i), :) corresponds with row A(i, :) 
A(:, 4) = B(index, 3); % add data to A 

另一種配方x,無需轉換到3D ,是:

x = bsxfun(@eq, A(:, 1), B(:,1)') & bsxfun(@eq, A(:, 2), B(:,2)'); 

該方法的缺點是它不能擴展到m礦石匹配列。

相關問題