How to delete rows and columns that are all zeros in a 3D array?
10 views (last 30 days)
Show older comments
I have a 1024 by 1024 by 150 array consisting of ones and zeros. How do i delete all the rows and columns containing all zeros and no ones, excluding the ones between ones. Example:
0 0 0 0 0
0 1 1 0 1
0 1 1 0 0
0 0 0 0 0
0 1 0 0 0
would result in :
1 1 0 1
1 1 0 0
0 0 0 0 this row would not get deleted because it is between rows containing ones
1 0 0 0
Looking at the original one:
row 1 got deleted because it contained all zeros and was not sandwiched between rows of ones
row 4 would not get deleted because it is sandwiched between rows containing ones
column 1 got deleted because it contained all zeros and was not sandwiched between columns of ones
column 4 would not get deleted because it is sandwiched between rows containing ones
Can you please answer the question with regards to the 1024 by 1024 by 150 array not a simple 2D array. Thanks
3 Comments
Accepted Answer
Adam Danz
on 28 Sep 2019
Edited: Adam Danz
on 28 Sep 2019
The first cellfun() below removes the leading and trailing columns of 0s from cell array data.
The second cellfun() below removes the leading and trailing rows of 0s from cell array data.
% demo data
data = {zeros(10,10), zeros(10,10)};
data{1}(sub2ind([10,10],[4,5,7,8],[3,5,6,7])) = 1;
data{2}(sub2ind([10,10],[3,5,7,10],[3,4,6,7])) = 1;
% Remove leading and trailing columns of 0
data = cellfun(@(x)x(:,find(any(x==1,1),1,'first'):find(any(x==1,1),1,'last')),data,'UniformOutput',false);
% [ first column with 1 ]:[ last column with 1 ]
% Remove leading and trailing rows of 0
data = cellfun(@(x)x(find(any(x==1,2),1,'first'):find(any(x==1,2),1,'last'),:),data,'UniformOutput',false);
% [ first row with 1 ]:[ last row with 1 ]
Note, if you're working with logical values rather than double 0s & 1s, you'll need to make this small change to both lines.
data = cellfun(@(x)x(:,find(any(x,1),1,'first'):find(any(x,1),1,'last')),data,'UniformOutput',false);
% here ^ here ^
2 Comments
Adam Danz
on 28 Sep 2019
Edited: Adam Danz
on 28 Sep 2019
Glad I could help!
The function is simply to find the first and last column (or row) that contains a 1.
data = cellfun(@(x)x(:,find(any(x==1,1),1,'first'):find(any(x==1,1),1,'last')),data,'UniformOutput',false);
% [ first column with 1 ]:[ last column with 1 ]
Sometimes it's helpful to break apart these long lines into their parts. The code below is a deconstruction of the line above but only operates on the first element of 'data'.
%Let's look at 'data'
data =
1×2 cell array
{10×10 double} {10×10 double}
data{1} % to see the matrix of 0s/1s
any(data{1}==1,1) % mark columns that contain a 1
ans =
1×10 logical array
0 0 1 0 1 1 1 0 0 0
find(any(data{1}==1,1),1,'first') % get the column number of the 1st 1
ans =
3
find(any(data{1}==1,1),1,'last') % get the column number of the LAST 1
ans =
7
% list all column numbers between the first and last
find(any(data{1}==1,1),1,'first'):find(any(data{1}==1,1),1,'last')
ans =
3 4 5 6 7
% pull out those columns from data{1}
data{1}(:,find(any(data{1}==1,1),1,'first'):find(any(data{1}==1,1),1,'last'))
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 1 0
0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
Then we do the same for row.
More Answers (0)
See Also
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!