Find the unique arrays in a list of arrays

6 vues (au cours des 30 derniers jours)
Marcus
Marcus le 19 Fév 2023
Commenté : Walter Roberson le 19 Fév 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.

Réponse acceptée

Marcus
Marcus le 19 Fév 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 commentaire
the cyclist
the cyclist le 19 Fév 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.

Connectez-vous pour commenter.

Plus de réponses (3)

Sulaymon Eshkabilov
Sulaymon Eshkabilov le 19 Fév 2023
Modifié(e) : Sulaymon Eshkabilov le 19 Fév 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 commentaires
Marcus
Marcus le 19 Fév 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 le 19 Fév 2023
Modifié(e) : Sulaymon Eshkabilov le 19 Fév 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.

Connectez-vous pour commenter.


the cyclist
the cyclist le 19 Fév 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 le 19 Fév 2023
Modifié(e) : Walter Roberson le 19 Fév 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 commentaires
the cyclist
the cyclist le 19 Fév 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 le 19 Fév 2023
Thanks for the check, @the cyclist !

Connectez-vous pour commenter.

Catégories

En savoir plus sur Matrices and Arrays dans Help Center et File Exchange

Produits


Version

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by