Joe Hesketh
Joe Hesketh

Reputation: 65

MATLAB: Splitting a matrix based on multiple values

I'm dealing with matrices of this format:

M =
1    1    3
1    1    1
1    2    2
1    2    1
1    2    2
2    1    5
2    1    1
2    2    3
2    2    4
2    2    2
...

What I want to do is extract sub matrices where the values in the first and second column can be grouped such that:

M1 =
1    1    3
1    1    1

M2 =
1    2    2
1    2    1
1    2    2

M3 =
2    1    5
2    1    1

...

I have been trying to think hard about how to index the matrix for this and I have a matrix available:

I =
1    1
1    2
2    1
2    2
...

that I could use for indexing. I was wondering if I could use it but I'm not 100% sure how. I don't want to use a for loop since the matrixes can be rather large and the order of complexity can become very large.

Thank you for reading!

Upvotes: 6

Views: 181

Answers (1)

Luis Mendo
Luis Mendo

Reputation: 112659

This is easily done with unique and accumarray:

M = [ 1    1    3
      1    1    1
      1    2    2
      1    2    1
      1    2    2
      2    1    5
      2    1    1
      2    2    3
      2    2    4
      2    2    2 ]; %// data
[~, ~, u] = unique(M(:,1:2), 'rows'); %// unique labels of rows based on columns 1 and 2
M_split = accumarray(u(:), (1:size(M,1)).', [], @(x){M(sort(x),:)}); %'// group rows 
                                                                     % // based on labels

This gives a cell array containing the partial matrices. In your example,

M_split{1} =
     1     1     3
     1     1     1
M_split{2} =
     1     2     2
     1     2     1
     1     2     2
M_split{3} =
     2     1     5
     2     1     1
M_split{4} =
     2     2     3
     2     2     4
     2     2     2

Upvotes: 12

Related Questions