How to delete rows and columns that are all zeros in a 3D array?

10 次查看(过去 30 天)
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 个评论
Mike Rovan
Mike Rovan 2019-9-28
What if it were done using a structure array? That way each of the 150 slices would be stored in a cell and would be able to be a different size. So there would be 150 cells each containing a different size matrix. And Yes those columns would be considered sandwiched. Basically the goal is to start from the top, delete all rows that contain all zeros. Then when it comes across a row that contains a one it stops. Then starts from the bottom upwards and does the same, stopping when it comes across a row that contains a one. Same thing with the columns, starting from the left, deleting all columns containing all zeros and stoping when a column contains a even a single one. Then does the same starting from the right side towards the left. This way the spacing (zeros) between 2 blobs of ones stays the same and only surrounding zeros are removed

请先登录,再进行评论。

采纳的回答

Adam Danz
Adam Danz 2019-9-28
编辑:Adam Danz 2019-9-28
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 个评论
Mike Rovan
Mike Rovan 2019-9-28
Works perfectly thanks! would you be able to explain the script a little though so that I am able to replicate it in the future. Thanks
Adam Danz
Adam Danz 2019-9-28
编辑:Adam Danz 2019-9-28
Glad I could help!
cellfun() applies a function to each element of a cell array, 'data'.
The function is simply to find the first and last column (or row) that contains a 1.
That is done with the function find().
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.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Matrices and Arrays 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by