Filtering the common rows between two matrices

6 visualizaciones (últimos 30 días)
Bassem Mokhtar
Bassem Mokhtar el 1 de Feb. de 2024
Movida: Dyuman Joshi el 25 de Feb. de 2024
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 comentarios
Stephen23
Stephen23 el 1 de Feb. de 2024
Movida: Dyuman Joshi el 25 de Feb. de 2024
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 el 25 de Feb. de 2024
Movida: Dyuman Joshi el 25 de Feb. de 2024
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.

Iniciar sesión para comentar.

Respuesta aceptada

Stephen23
Stephen23 el 1 de Feb. de 2024
Editada: Stephen23 el 1 de Feb. de 2024
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.

Más respuestas (0)

Categorías

Más información sobre Logical en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by