Split array according to one column values

I have an array like this:
A = {10 1 1; 10 1 2; 10 1 1; 10 2 1; 10 1 3; 10 2 4; 10 2 5}
I want to split into arrays based on the second column value. The output should look like this:
B = {10 1 1; 10 1 2; 10 1 1; 10 1 3}
C = {10 2 1; 10 2 4; 10 2 5}
How can I do this ?

2 Comments

What would you recommend if you have a large array and an unknown number of different values in the indexing column?

Sign in to comment.

Answers (3)

Stephen23
Stephen23 on 25 Jul 2018
Edited: Stephen23 on 25 Jul 2018
Your life would be much easier if you stored numeric data in numeric arrays:
>> A = [10 1 1; 10 1 2; 10 1 1; 10 2 1; 10 1 3; 10 2 4; 10 2 5]
A =
10 1 1
10 1 2
10 1 1
10 2 1
10 1 3
10 2 4
10 2 5
>> B = A(A(:,2)==1,:)
B =
10 1 1
10 1 2
10 1 1
10 1 3
>> C = A(A(:,2)==2,:)
C =
10 2 1
10 2 4
10 2 5

4 Comments

Thanks for the fast response :)
What I represented has a example, I can have several values in the 2nd column (sorry if I didn't explained this). That way I would have to know in the first hand the values I have.
@Rui Carapinha: there are several approaches. Here is one simple solution using unique and arrayfun:
>> A = [10,1,1;10,1,2;10,1,1;10,2,1;10,1,3;10,2,4;10,2,5]
A =
10 1 1
10 1 2
10 1 1
10 2 1
10 1 3
10 2 4
10 2 5
>> U = unique(A(:,2));
>> C = arrayfun(@(n)A(A(:,2)==n,:),U,'uni',0);
>> C{:}
ans =
10 1 1
10 1 2
10 1 1
10 1 3
ans =
10 2 1
10 2 4
10 2 5
Another approach using FINDGROUPS and SPLITAPPLY:
A = [10,1,1;10,1,2;10,1,1;10,2,1;10,1,3;10,2,4;10,2,5]
A = 7×3
10 1 1 10 1 2 10 1 1 10 2 1 10 1 3 10 2 4 10 2 5
G = findgroups(A(:,2));
C = splitapply(@(m){m},A,G)
C = 2×1 cell array
{4×3 double} {3×3 double}
C{:}
ans = 4×3
10 1 1 10 1 2 10 1 1 10 1 3
ans = 3×3
10 2 1 10 2 4 10 2 5
You could potentially also use groupsummary and use it to perform whatever operations you'd perform on the matrices stored in the cells of C.

Sign in to comment.

B=A(cellfun(@(x) isequal(1,x),{A{:,2}}),:)
C=A(cellfun(@(x) isequal(2,x),{A{:,2}}),:)
Maybe like this?
You should be able to do this through logical indexing, and it may be easier if it was not a cell array but a normal numerical array. Define the matrix as such, without the curly braces:
A = [10 1 1; 10 1 2; 10 1 1; 10 2 1; 10 1 3; 10 2 4; 10 2 5];
Then store the second column into a separate variable:
cols = A(:,2);
This takes the second column of the A matrix and stores it into a column vector called "cols". From there you can use logical indexing as follows:
ones = cols ==1;
twos = cols ==2;
The output of the above two commands should be this:
ones =
7×1 logical array
1
1
1
0
1
0
0
"Ones" will have a "1" whenever the column vector has a "1" and has a "0" whenever the column vector has anything other than a 1. The same logic then applies to the variable "twos"
From here you can then call the following two commands to get what you are looking for:
B = A(ones,:)
C = A(twos,:)
This is logical indexing, a neat feature of MATLAB, let me know if you need further clarification or if you have any questions!

Categories

Asked:

on 25 Jul 2018

Commented:

on 23 Aug 2022

Community Treasure Hunt

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

Start Hunting!