How extract sub matrix without zeros from a big matrix

6 ビュー (過去 30 日間)
gianluca scutiero
gianluca scutiero 2017 年 11 月 3 日
編集済み: Cedric 2017 年 11 月 3 日
Hello everybody ... I have a big matrix [N] as shown in Figure. I need to extract sub-matrix from [N]: [A],[B],[C],[D], [E] .... The end of each row can contain some zeros (red part). So I need to extract these sub-matrix. If [A] has the same number of columns of [E], I have to combine them in a unique matrix ([F]=[A];[E]). [N] does not contain zeros in the white part. Could you help me with this problem? Thank you very much for your time
  2 件のコメント
KL
KL 2017 年 11 月 3 日
what do you mean by big matrix? be specific? what's the size? How do you identify A,B,C,D and E within N? How are they distributed across N's rows?
gianluca scutiero
gianluca scutiero 2017 年 11 月 3 日
big matrix is about 30000x16. Because the zeros are at the end of each row. I have attached an example of the matrix. For example here A can be made by the first 3 rows.

サインインしてコメントする。

採用された回答

Cedric
Cedric 2017 年 11 月 3 日
編集済み: Cedric 2017 年 11 月 3 日
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 件のコメント
Cedric
Cedric 2017 年 11 月 3 日
編集済み: Cedric 2017 年 11 月 3 日
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 ...

サインインしてコメントする。

その他の回答 (2 件)

Guillaume
Guillaume 2017 年 11 月 3 日
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})});
  3 件のコメント
Guillaume
Guillaume 2017 年 11 月 3 日
"But is there the possibility to join the rows generated with the same numbers of columns ?"
That's the whole purpose of the last three lines.
gianluca scutiero
gianluca scutiero 2017 年 11 月 3 日
Sorry !!!! I appreciated very much your help ... thank you :)

サインインしてコメントする。


gianluca scutiero
gianluca scutiero 2017 年 11 月 3 日
Thank you very much, Cedric Wannaz. It works very well. :)
  1 件のコメント
Cedric
Cedric 2017 年 11 月 3 日
編集済み: Cedric 2017 年 11 月 3 日
My pleasure, but please see my last edits: the extra operations truncate zeros and manage cases with zeros inside the non-zero blocks!

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by