# How extract sub matrix without zeros from a big matrix

12 views (last 30 days)

Show older comments

gianluca scutiero
on 3 Nov 2017

Edited: Cedric Wannaz
on 3 Nov 2017

### Accepted Answer

Cedric Wannaz
on 3 Nov 2017

Edited: Cedric Wannaz
on 3 Nov 2017

Here is an example; we first build a test data set:

>> N = randi( 10, 10, 4 ) ;

>> for k = 1 : 10, N(k,1+randi(3,1):end) = 0 ; end

>> N

N =

8 0 0 0

3 3 9 0

6 0 0 0

7 3 0 0

9 0 0 0

10 4 0 0

6 0 0 0

2 3 0 0

2 7 4 0

3 5 6 0

Then sorting/grouping can be achieved as follows:

>> gId = sum( N == 0, 2 ) ;

>> groups = splitapply( @(x){x}, N, gId ) ;

With that you get:

>> groups

groups =

3×1 cell array

{3×4 double}

{3×4 double}

{4×4 double}

>> groups{1}

ans =

3 3 9 0

2 7 4 0

3 5 6 0

>> groups{2}

ans =

7 3 0 0

10 4 0 0

2 3 0 0

>> groups{3}

ans =

8 0 0 0

6 0 0 0

9 0 0 0

6 0 0 0

This assumes that there is no zero aside from the trailing ones on each row. We can work releasing this requirement if there can be zeros elsewhere, and on truncation to the non-zero part if you really need it.

EDIT : Here are the few extra steps if you wanted to deal with situations with zeros in the middle of non-zeros, and if you needed truncation: I start by adding a zeros in N(9,2) to test that it is working:

>> N(9,2) = 0 ;

Then

>> [r, c] = find( N ) ;

last_nzc = splitapply( @max, c, r ) ;

gId = findgroups( size(N, 2) - last_nzc + 1 ) ;

groups = splitapply( @(x,c){x(:,1:c(1))}, N, last_nzc, gId ) ;

With that we get:

>> groups{1}

ans =

3 3 9

2 0 4

3 5 6

>> groups{2}

ans =

7 3

10 4

2 3

>> groups{3}

ans =

8

6

9

6

##### 1 Comment

Cedric Wannaz
on 3 Nov 2017

Edited: Cedric Wannaz
on 3 Nov 2017

Note that I initially wrote x(:,1:c) in the call to SPLITAPPLY, which went through. That is surprising(!) This lead me to evaluate the following:

>> 1 : [4,5,6]

ans =

1 2 3 4

which is interesting ...

### More Answers (2)

Guillaume
on 3 Nov 2017

If I understood correctly:

%N: your big matrix

rowswithnozeros = cellfun(@(row) nonzeros(row).', num2cell(N, 2), 'UniformOutput', false);

rowlength = cellfun(@numel, rowswithnozeros);

[~, ~, subs] = unique(rowlength, 'stable'); %s'stable' optional

matriceswithnozeros = accumarray(subs, (1:numel(rowswithnozeros))', [], @(rows) {vertcat(rowswithnozeros{rows})});

gianluca scutiero
on 3 Nov 2017

##### 1 Comment

Cedric Wannaz
on 3 Nov 2017

Edited: Cedric Wannaz
on 3 Nov 2017

### See Also

### Categories

### Community Treasure Hunt

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

Start Hunting!