【问题标题】:value in new column if two values if two columns match two others Matlab新列中的值如果两个值如果两列匹配另外两个 Matlab
【发布时间】:2017-05-25 19:08:11
【问题描述】:

所以我有两个很长的矩阵。示例如下:

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 个矩阵匹配的前两列中的值(相同)。

所以输出矩阵:

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

最好的方法是什么?

提前致谢

【问题讨论】:

  • 你的方法是什么?首先提出几个更容易,在你的问题中描述它们,这样我们就可以告诉你哪个更好,或者替代一个更好。在我看来,如果你赶时间的话,两个for 循环就可以完成这项工作。
  • 我认为C 中的最后一个11 应该是114,对吗?

标签: matlab join matrix matching


【解决方案1】:

使用ismember 的第二个输出和'rows' 选项来获取匹配的索引,您可以从中轻松构建结果:

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

【讨论】:

  • 我想你的意思是C = [A B(ind,3)];。但这是一个非常优雅的解决方案!
  • 我不知何故忽略了你的回答。对不起,它真的很好用。非常优雅和快速。非常感谢你们!
【解决方案2】:

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 循环不漂亮?
  • 顺便说一句,你可以all(B(idx,1:2)== A(:,1:2),2) 代替all 确实需要额外的参数来指示尺寸。
  • 也许我对 for 循环有点敏感,但我尽量避免它们,因为它们往往是瓶颈,并且通常可以使用智能矩阵索引来避免。谢谢关于all()的提示!
  • 我认为在这种情况下这是一个简单的比较,并且您正确使用了索引,因此它是 IMO 最有效的解决方案(而且漂亮、易于阅读)。当然,不费脑筋也很容易上手。
  • 我想我会选择 Imoes 的解决方案,因为我能够理解它并且它也适用于未排序的列。但是你能告诉我Imoes和Y.Y Chang的选择有什么区别吗?我很清楚 Chang 会缩短计算时间,但如何?
【解决方案3】:

没有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 的另一种公式是:

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

这种方法的缺点是它无法扩展到更多匹配的列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-22
    • 2015-02-11
    • 2016-07-28
    • 2016-06-19
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    相关资源
    最近更新 更多