所以我有两个非常长的矩阵。下面给出了一个样本:
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 :(得分:4)
使用ismember
的第二个输出和'rows'
选项来获取匹配的索引,从中可以轻松构建结果:
[~, ind] = ismember(A(:, [1 2]), B(:, [1 2]), 'rows');
C = [A B(ind, 3)];
答案 1 :(得分: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
答案 2 :(得分: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)');
这种方法的缺点是它不易扩展到更匹配的列。