One/zero Matrix, merge subset of columns

1 view (last 30 days)
Rub Ron
Rub Ron on 13 Dec 2020
Edited: Jan on 16 Dec 2020
Say I have this matrix of ones and zeros, 10x6:
x= [ 0 0 0 1 0 0
0 1 1 1 1 1
0 1 1 0 1 1
0 0 0 0 0 0
0 0 0 0 0 0
1 0 0 0 0 0
0 0 1 1 1 1
0 0 0 0 0 1
0 0 0 0 0 1
0 0 0 0 1 1];
I would like to remove the columns that are a subset of any other column. For instance, column 2 is a subset of column 3 (because all ones in column 2 are in the same rows of column 3). Similarly column 3 is a subset of column 6, then columns 3 should be eliminated. At the end only the columns are not "subset" of other should remain only. So in the example, I should get:
0 1 0
0 1 1
0 0 1
0 0 0
0 0 0
1 0 0
0 1 1
0 0 1
0 0 1
0 0 1
The order of te columns is not importan, but the speed.
Any hint will be very much appreciatted. Thanks!

Accepted Answer

Jan
Jan on 16 Dec 2020
Edited: Jan on 16 Dec 2020
x0 = [ 0, 0, 0, 1, 0, 0; ...
0, 1, 1, 1, 1, 1; ...
0, 1, 1, 0, 1, 1; ...
0, 0, 0, 0, 0, 0; ...
0, 0, 0, 0, 0, 0; ...
1, 0, 0, 0, 0, 0; ...
0, 0, 1, 1, 1, 1; ...
0, 0, 0, 0, 0, 1; ...
0, 0, 0, 0, 0, 1; ...
0, 0, 0, 0, 1, 1];
% Save memory:
x = logical(x0);
for Iter = 1:2 % From left to right and right to left
nCol = size(x, 2);
del = false(1, nCol);
for iCol = 1:nCol
col = x(:, iCol);
for jCol = iCol + 1:nCol
if all(and(col, x(:, jCol)) == col)
del(iCol) = true;
break
end
end
end
x(:, del) = [];
x = x(:, end:-1:1); % Change order
end
Another apporach:
x = logical(x0); % Save memory
nCol = size(x, 2);
del = false(1, nCol);
for iCol = 1:nCol
if ~del(iCol)
col = x(:, iCol);
for jCol = iCol + 1:nCol
if ~del(jCol)
both = and(col, x(:, jCol));
if all(both == x(:, jCol))
del(jCol) = true;
elseif all(both == col)
del(iCol) = true;
break
end
end
end
end
end
x(:, del) = [];

More Answers (1)

Image Analyst
Image Analyst on 13 Dec 2020
Try this. It will give you what you wanted.
x= [ 0 0 0 1 0 0
0 1 1 1 1 1
0 1 1 0 1 1
0 0 0 0 0 0
0 0 0 0 0 0
1 0 0 0 0 0
0 0 1 1 1 1
0 0 0 0 0 1
0 0 0 0 0 1
0 0 0 0 1 1];
[rows, columns] = size(x)
% Initialize an array of the columns we may need to delete.
columnsToDelete = false(1, columns);
for col = 1 : columns
% Get this Column
thisColumn = x(:, col);
% Scan the other columns.
for col2 = col + 1 : columns
otherColumn = x(:, col2);
% And them together and see if it's the same as the first column
anded = thisColumn & otherColumn;
if all(anded == thisColumn)
% It's a subset.
fprintf('Column %d is a subset of column %d.\n', col, col2);
% Log that col is a subset of some other column.
columnsToDelete(col) = true;
end
end
end
% Now delete those columns that were determined to be
% a subset of any of the columns to the right in the array.
xOut = x; % First initialize a copy for the output.
% Now delete the columns we need to.
xOut(:, columnsToDelete) = [] % Setting to null removes the column.
You could also just extract the columns you want, so instead of the last few lines, have this:
% Now take a subset of any of the columns in the array
% by taking the inverse of the logical vector.
xOut = x(:, ~columnsToDelete); % Extract the columns we want.
They're just 2 different ways of getting xOut.
  4 Comments
Rub Ron
Rub Ron on 13 Dec 2020
Now,it does not work with this x:
0 0 0 0 0
1 1 1 0 1
1 1 1 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 1 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 1 0 1
1 1 1 1 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 1 0 1
0 0 0 0 0
it should give:
0
1
1
0
0
0
0
0
1
0
0
0
0
1
1
0
0
0
0
1
0
Image Analyst
Image Analyst on 16 Dec 2020
Well, column 1 was a subset of column 2 so it got deleted.

Sign in to comment.

Categories

Find more on Matrices and Arrays in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!