I have two matrices A and B. Matrix A consists of 3 columns and matrix B consists of 4 columns.
A = [1 2 3; 4 5 6; 7 8 9];
B = [1 2 3 90; 3 1 2 88; 4 5 6 17; 6 5 4 19; 7 8 9 12; 15 18 22 20];
And I want to filter the common rows between matrix A and B according to each row of A and store the common rows of matrix B in a cell. This cell consists of multiple arrays equal to the number of the rows of matrix A.
The expected result should be something like that:
matching_cell{1} = [1 2 3 90; 3 1 2 88];
matching_cell{2} = [4 5 6 17; 6 5 4 19];
matching_cell{3} = [7 8 9 12];
Note: I do not want to use neasted for loop with ismember as the matrices dimensions are large and it will take a lot of time to run.
Thanks.

댓글 수: 3

Try this -
A = [1 2 3; 4 5 6; 7 8 9];
B = [1 2 3 90; 3 1 2 88; 4 5 6 17; 6 5 4 19; 7 8 9 12; 15 18 22 20];
%sort each row ascendigly
C = sort(B,2)
C = 6×4
1 2 3 90 1 2 3 88 4 5 6 17 4 5 6 19 7 8 9 12 15 18 20 22
%Compare rows
[idx1,idx2]=ismember(C(:,1:size(A,2)), A, 'rows');
%Split into cell arrays according to the groups
out = splitapply(@(x) {x}, B(idx1,:), idx2(idx1))
out = 3×1 cell array
{2×4 double} {2×4 double} {[7 8 9 12]}
out{1}
ans = 2×4
1 2 3 90 3 1 2 88
Assumptions made -
> Rows in A are already sorted ascendingly
> B (and thus C) has atleast the same amount of columns as A
Note that SPLITAPPLY will fail if any row of A does not exist in B (or produce a shorter output array):
A = [1 2 3; 0 0 0; 4 5 6];
B = [1 2 3 90; 3 1 2 88; 4 5 6 17; 6 5 4 19; 7 8 9 12; 15 18 22 20];
C = sort(B,2);
[idx1,idx2]=ismember(C(:,1:size(A,2)), A, 'rows');
out = splitapply(@(x) {x}, B(idx1,:), idx2(idx1))
Error using splitapply
For N groups, every integer between 1 and N must occur at least once in the vector of group numbers.
Dyuman Joshi
Dyuman Joshi 2024년 2월 25일
이동: Dyuman Joshi 2024년 2월 25일
Yes, Thank you for pointing it out, I am aware of the requirement of spliapply() as stated in the error message.
As of now, I can't seem think of a solution that would work for all cases, so I am moving my answer to a comment, and accepting your answer as it provides a robust solution.

댓글을 달려면 로그인하십시오.

 채택된 답변

Stephen23
Stephen23 2024년 2월 1일
편집: Stephen23 2024년 2월 1일
A = [1,2,3; 4,5,6; 7,8,9]
A = 3×3
1 2 3 4 5 6 7 8 9
B = [1,2,3,90; 3,1,2,88; 4,5,6,17; 6,5,4,19; 7,8,9,12; 15,18,22,20]
B = 6×4
1 2 3 90 3 1 2 88 4 5 6 17 6 5 4 19 7 8 9 12 15 18 22 20
[X,Y] = ismember(sort(B(:,1:3),2),A,'rows');
F = @(n)B(n==Y,:);
C = arrayfun(F,1:size(A,1),'uni',0)
C = 1×3 cell array
{2×4 double} {2×4 double} {[7 8 9 12]}
C{:}
ans = 2×4
1 2 3 90 3 1 2 88
ans = 2×4
4 5 6 17 6 5 4 19
ans = 1×4
7 8 9 12
This will produce a consistent 1*size(A,1) output cell array, even if there are rows that do not match.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Resizing and Reshaping Matrices에 대해 자세히 알아보기

태그

질문:

2024년 2월 1일

이동:

2024년 2월 25일

Community Treasure Hunt

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

Start Hunting!

Translated by