Find the unique arrays in a list of arrays

10 visualizaciones (últimos 30 días)
Marcus
Marcus el 19 de Feb. de 2023
Comentada: Walter Roberson el 19 de Feb. de 2023
Hi everyone.
This question is easy to describe, but I can't think of an easy way to do it. Given a list of binary matrices (i.e., elements are all '1's and '0's), how do I remove any duplicate matrices from that list. I.e,, I only want the unique matrices. Note that matrices in this list do not necessarily have to be the same size. For example, if
A = [0 1 1;1 1 1], B = [1 1 1;0 0 1], C = [0 1 1;1 1 1], D = [1 0;1 1]
Then the procedure must automatically remove either A or C as they are identical. By the way, I was thinking of storing all my arrays in a cell array.
Thank you.
Marcus.

Respuesta aceptada

Marcus
Marcus el 19 de Feb. de 2023
Think I've found what I need. This code loops through each matrix in the list and checks if it's already in the unique_mats array using the isequal() function. If it's not already in the array, the current matrix is added to the unique_mats array. At the end of the loop, the code displays the unique matrices. PS: Chat GPT wrote this code for me !!!
% Example list of matrices
mat_list = { [0 1 1;1 1 1], [1 1 1;0 0 1], [0 1 1;1 1 1], [1 0;1 1] };
% Initialize empty array to store unique matrices
unique_mats = {};
% Loop through each matrix in the list
for i = 1:numel(mat_list)
mat = mat_list{i};
% Check if the current matrix is unique
is_unique = true;
for j = 1:numel(unique_mats)
if isequal(mat, unique_mats{j})
is_unique = false;
break;
end
end
% Add the current matrix to the unique_mats array if it's unique
if is_unique
unique_mats{end+1} = mat;
end
end
% Display the unique matrices
unique_mats{:}
  1 comentario
the cyclist
the cyclist el 19 de Feb. de 2023
This solution follows the same principle as mine, but I would expect it will be faster because it will avoid some of the pairwise comparisons (where mine does all of them).
Good AI.

Iniciar sesión para comentar.

Más respuestas (3)

Sulaymon Eshkabilov
Sulaymon Eshkabilov el 19 de Feb. de 2023
Editada: Sulaymon Eshkabilov el 19 de Feb. de 2023
One of the viable fcns to use here is isequal(), e.g.:
A = [0 1 1;1 1 1]; B = [1 1 1;0 0 1]; C = [0 1 1;1 1 1];
ALL{1} = A;
ALL{2} = B;
ALL{3} = C;
if isequal(ALL{1}, ALL{2})
ALL{2}=[];
elseif isequal(ALL{2}, ALL{3})
ALL{3} = [];
elseif isequal(ALL{1}, ALL{3})
ALL{3} = [];
else
displ('OK')
end
ALL{:}
ans = 2×3
0 1 1 1 1 1
ans = 2×3
1 1 1 0 0 1
ans = []
  2 comentarios
Marcus
Marcus el 19 de Feb. de 2023
Yes, I see that this works. But this approach becomes very awkward if the number of matrices is even modestly large, e.g. >= 10. What would you do if there were 50 matrices to compare?
Sulaymon Eshkabilov
Sulaymon Eshkabilov el 19 de Feb. de 2023
Editada: Sulaymon Eshkabilov el 19 de Feb. de 2023
for .. end loop or switch might be an option. There might be some other more efficient ways to get it done for larger sizes.

Iniciar sesión para comentar.


the cyclist
the cyclist el 19 de Feb. de 2023
% Input
A = [0 1 1;
1 1 1];
B = [1 1 1;
0 0 1];
C = [0 1 1;
1 1 1];
D = [1 0;
1 1];
% Put them in cell array (as you suggested)
cellABCD = {A, B, C, D};
% Get the number of arrays
numberArrays = numel(cellABCD);
% Preallocate the array that holds the equality check
equalityCheck = zeros(numberArrays,numberArrays);
% For each unique pair of arrays, check for equality
for nc1 = 1:numberArrays
for nc2 = (nc1+1):numberArrays
equalityCheck(nc1,nc2) = isequal(cellABCD(nc1),cellABCD(nc2));
end
end
% Find the indices of the duplicates
[~,indexToDuplicate] = find(equalityCheck);
% Initialize the solution to be the full array, then delete the duplicates
uniqueCellABCD = cellABCD;
uniqueCellABCD(indexToDuplicate) = [];

Walter Roberson
Walter Roberson el 19 de Feb. de 2023
Editada: Walter Roberson el 19 de Feb. de 2023
find the maximum number of rows and columns and do a pass that pads each array with inf to maximum rows and columns and reshape to row. put all the rows into a 2d array. unique by rows and take the second output; that will be indices to one copy of each unique matrix, so retrieve those into your output.
This relies on the padding being a value not found in the matrices. Possibly nan would work but I didn't want to have to deal with the question of whether unique treats nan as equal.
  2 comentarios
the cyclist
the cyclist el 19 de Feb. de 2023
Indeed, padding with NaN will not serve the purpose here ...
unique([0 1 NaN; 0 1 NaN],"rows")
ans = 2×3
0 1 NaN 0 1 NaN
unique([0 1 Inf; 0 1 Inf],"rows")
ans = 1×3
0 1 Inf
Walter Roberson
Walter Roberson el 19 de Feb. de 2023
Thanks for the check, @the cyclist !

Iniciar sesión para comentar.

Categorías

Más información sobre Matrices and Arrays en Help Center y File Exchange.

Productos


Versión

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by