How to compare and find the differences in each cell inside a cell structure array?
15 次查看(过去 30 天)
显示 更早的评论
Hi there,
Originally I have a matrix size of 120x8 in my workspace. Assume it is named 'A1'.
Each line/row in the matrix is unique with no repeats. (Basically like truth table)
But for my calculation, I regenerated it with more variables, and enlarge the entire matrix, becoming a 960x8 matrix.
Then I use 'mat2cell' and reform them in square size, creating a cell array with 1x120 cells, with each cell contains an 8x8 matrix.
So now I have 1x120 cell array with each cell an 8x8 matrix within.
But then, some cells maybe the same, some maybe the same but in a different order.
How do I distinguish the different matrices and eliminate any similar ones?
Thank you very much.
4 个评论
采纳的回答
Adam Danz
2019-4-22
编辑:Adam Danz
2019-4-22
See the comments within the solution for an explanation of the methods. The basic approach is to convert your data to binary format ( [-1,1] to [0,1] ) and then to decimal format using bi2de(). That way each row of [-1 -1 1 1] values is represented by a single value (eg: bi2de([0 0 1 1]) = 12 ). Then we just need to search for cell arrays with the same sorted vectors.
% Create fake data to work with
A1{1} = 2*(rand(8)>.5) - 1;
A1{2} = 2*(rand(8)>.5) - 1;
A1{3} = 2*(rand(8)>.5) - 1;
A1{4} = 2*(rand(8)>.5) - 1;
A1{5} = A1{1}; %Repeat of {1}
A1{6} = 2*(rand(8)>.5) - 1;
A1{7} = A1{2}; %Repeat of {2}
A1{8} = 2*(rand(8)>.5) - 1;
A1{9} = A1{3}([1 8 2 7 3 6 4 5],:); %Repeat of {3} and different row order
A1{10} = 2*(rand(8)>.5) - 1;
% Temporarily replace -1 with 0 to produce binary values
A1bin = cellfun(@(x)(x+1)/2, A1, 'UniformOutput', false);
% Convert from binary to decimal, sorted (result will be a vector for each cell element)
A1dec = cellfun(@(x)sort(bi2de(x)), A1bin, 'UniformOutput', false);
% Convert to a matrix and find matching columns
A1mat = cell2mat(A1dec);
[~, unqRowIdx] = unique(A1mat', 'rows','stable');
% Note: In the fake data, elements 5, 7, 9 are duplicates
% The unqRowIdx should list all other elements except those.
% Extract unique cell elements using the column idx
A1unq = A1(unqRowIdx);
Note, bi2de() requires the Communications toolbox. If you don't have this toolbox, you can use bin2dec() instead:
A1dec = cellfun(@(x)sort(bin2dec(num2str((x)))), A1bin, 'UniformOutput', false);
2 个评论
Adam Danz
2019-4-22
编辑:Adam Danz
2019-4-22
Are you using the same input data? If you're running my code that generates a fake dataset, those data are random so they will produce different inputs each time (unless you set the rng seed).
I tested both lines with the same input data (without regenerating a new random dataset) and they produced identical results.
"im not sure whether I installed that specific toolbox",
you can run this line of code which produces the following output that indicates the toolbox (comm = communications toolbox).
which('bi2de')
% ans: C:\Program Files\MATLAB\R2018a\toolbox\comm\comm\bi2de.m
% or
% ans: 'bi2de' not found. (<- you don't have this function)
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!