Find columns with same values in matrix
19 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Manuel Schmidberger
am 26 Apr. 2019
Kommentiert: Manuel Schmidberger
am 3 Mai 2019
Hi,
I actually struggle on a fast and good solution on finding columns in an 2D matrix containing same values and returning the row index of those columns.
% Example:
A = [2,2,7,3; ...
8,7,8,10; ...
4,3,5,2; ...
6,7,1,9];
Result should be 2 and 4 because in column 2 the number 7 occurs two times. Is there anything similar to unique or anything else? I try to avoid looping every column with unique since there will be a lot of matrices and bigger ones.
Thanks a lot!
2 Kommentare
Akzeptierte Antwort
Adam Danz
am 26 Apr. 2019
Bearbeitet: Adam Danz
am 2 Mai 2019
I changed your example matrix to include a variety of duplicates.
% Example:
A = [2,2,7,3,5,0;8,7,8,10,5,0;4,3,5,3,9,0;6,7,1,9,9,1];
A =
2 2 7 3 5 0
8 7 8 10 5 0
4 3 5 3 9 0
6 7 1 9 9 1
As you can see, columns 2, 4, 5 & 6 have duplicates and column 5 has 2 sets while column 6 has three of the same value.
% identify the duplicate values
dupIdx = splitapply(@(x){histc(x,unique(x))>1}, A, 1:size(A,2));
unqVals = splitapply(@(x){unique(x)}, A, 1:size(A,2));
dupVals = cellfun(@(x,y)x(y), unqVals, dupIdx, 'UniformOutput', false);
% List the rows that contain duplicate values for each column
dupRows = splitapply(@(x,y) {find(ismember(x,[y{:}]))}, A, dupVals, 1:size(A,2));
% List the column numbers that contain duplicates
hasDup = find(~cellfun(@isempty, dupRows));
So, dupRows{2} will list the row numbers of column 2 that contain a duplicate. It's empty if col 2 has no duplicates.
hasDup is a vector of column numbers that contain a duplicate. It's empty if there are no duplicates in any column.
[UPDATE] For matlab releases before 2015b, here's the same method using cellfun() instead of splitapply()
% Example:
A = [2,2,7,3,5,0;8,7,8,10,5,0;4,3,5,3,9,0;6,7,1,9,9,1];
Acell = mat2cell(A,size(A,1),ones(1,size(A,2)));
dupIdx = cellfun(@(x){histc(x,unique(x))>1}, Acell);
unqVals = cellfun(@(x){unique(x)}, Acell);
dupVals = cellfun(@(x,y)x(y), unqVals, dupIdx, 'UniformOutput', false);
% List the rows that contain duplicate values for each column
dupRows = cellfun(@(x,y) find(ismember(x,y(:))), Acell, dupVals,'UniformOutput', false);
% List the column numbers that contain duplicates
hasDup = find(~cellfun(@isempty, dupRows));
% Alternative
% hasDup = any(([ones(1,size(A,2));diff(sort(A))]~=0)==0);
3 Kommentare
Adam Danz
am 2 Mai 2019
splitapply() came out in r2015b. I updated my solution to include a second method using cellfun() instead of splitapply(). It's the same logic; just adapted to cellfun().
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Migrate GUIDE Apps finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!