Finding correct row in array with multiple columns matching different conditions

22 次查看(过去 30 天)
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

采纳的回答

DGM
DGM 2021-4-25
编辑:DGM 2021-4-25
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 个评论
Avinash Rajendra
Avinash Rajendra 2021-4-25
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!
DGM
DGM 2021-4-25
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 个)

the cyclist
the cyclist 2021-4-25
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

类别

Help CenterFile Exchange 中查找有关 Matrix Indexing 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by