Finding correct row in array with multiple columns matching different conditions

I have the following example and want to find the correct row. I have a for loop that does the job, but need an alternative solution for performance and efficiency reasons. Any help will be appreciated. Thanks in advance!
A = [1 2 3;
4 5 6]; % 2 rows and 3 columns
B = [1 1 2;
1 2 3;
2 2 4;
3 4 5;
4 5 6]; % 5 rows and 3 columns
What I need is the row in B where all the values of the row are respectively equal to the values of one subject row in A. In the example, all the values of the second row of B match all the values of the first row of A, and similarly with the fifth row of B and the second row of A. So, my output should be [2; 5]. One point to note is that there will only be one row in B where all its values will match those of the subject row in A.
My for loop works like this:
indices = ones(size(A, 1), 1); %size of indices = 2 rows and 1 column
for k = 1:size(A, 1) %k will go from 1 to 2; k defines subject row
C = A(k, 1:end); % C = [1 2 3] for k = 1, C = [4 5 6] for k = 2
D = find(B(1:end, 1) == C(1); % 1 and 2 for k = 1, 5 for k = 2
E = find(B(1:end, 2) == C(2); % 2 and 3, 5 for k = 2
F = find(B(1:end, 3) == C(3); % 2 for k = 1, 5 for k = 2
indices(k, 1) = intersect(intersect(D, E), F); % 2 for k = 1, 5 for k = 2
end

 采纳的回答

Maybe something like this:
A = [1 2 3; 4 5 6]; % 2 rows and 3 columns
B = [1 1 2; 1 2 3; 2 2 4; 3 4 5; 4 5 6]; % 5 rows and 3 columns
% this is a logical index of the rows which match
C = any(all(bsxfun(@eq,B,permute(A,[3 2 1])),2),3)
gives
C =
5×1 logical array
0
1
0
0
1
For most indexing purposes, this may suffice. If you really need the list of row subscripts, just do
C = find(C)

2 个评论

The answer quotes the ismember function, which I found works perfectly for this problem. But, your answer works as well, so I'm accepting it. Thanks!
For what it's worth, I consider ismember() a matter of convenience. It gives the correct answers and the syntax is simple, but if speed is of value, there are usually better options. On my system, in either R2015b or R2019b, this:
C = ismember(B,A,'rows');
takes about 13-14 times as long as this convoluted mess:
C = any(all(bsxfun(@eq,B,permute(A,[3 2 1])),2),3);
Your case likely doesn't need the speed, but it's good to be aware of the penalties so that you can make the judgement when it does matter.

请先登录,再进行评论。

更多回答(1 个)

A = [1 2 3;
4 5 6]; % 2 rows and 3 columns
B = [1 1 2;
1 2 3;
2 2 4;
3 4 5;
4 5 6]; % 5 rows and 3 columns
indices = find(ismember(B,A,'rows'))
indices = 2×1
2 5

类别

帮助中心File Exchange 中查找有关 Matrix Indexing 的更多信息

产品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by