所以我有两个很长的矩阵。下面给出了一个示例:
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];
我想要一个 Thirds 矩阵,它将第一个矩阵与第二个矩阵的第三列组合在一起,基于 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];
最好的方法是什么?
提前致谢
使用 ismember
的第二个输出和 'rows'
选项来获取匹配的索引,从中可以轻松构建结果:
[~, ind] = ismember(A(:, [1 2]), B(:, [1 2]), 'rows');
C = [A B(ind, 3)];
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
可以在没有 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)');
此方法的缺点是它不太可扩展到更多匹配的列。