A = [1,4,2,5,10
2,4,5,6,2
2,1,5,6,10
2,3,5,4,2]
And I want split it into two matrix by the last column A ->B and C
B
Here is a general approach which will work on any number of numbers in the last column on any sized matrix:
A = [1,4,2,5,10
2,4,5,6,2
1,1,1,1,1
2,1,5,6,10
2,3,5,4,2
0,0,0,0,2];
First sort by the last column (many ways to do this, don't know if this is the best or not)
[~, order] = sort(A(:,end));
As = A(order,:);
Then create a vector of how many rows of the same number appear in that last col (i.e. how many rows per group)
rowDist = diff(find([1; diff(As(:, end)); 1]));
Note that for my example data rowDist
will equal [1 3 2]
as there is 1 1
, 3 2
s and 2 10
s.
Now use mat2cell
to split by these row groupings:
Ac = mat2cell(As, rowDist);
If you really want to you can now split it into separate matrices (but I doubt you would)
Ac{:}
results in
ans =
1 1 1 1 1
ans =
0 0 0 0 2
2 3 5 4 2
2 4 5 6 2
ans =
1 4 2 5 10
2 1 5 6 10
But I think you would find Ac
itself more useful
EDIT:
Many solutions so might as well do a time comparison:
A = [...
1 4 2 5 10
2 4 5 6 2
2 1 5 6 10
2 3 5 4 2
0 3 1 4 9
1 3 4 5 3
1 0 4 5 9
1 2 4 3 1];
A = repmat(A, 1000, 1);
tic
for l = 1:100
[~, y] = sort(A(:,end));
As = A(y,:);
rowDist = diff(find([1; diff(As(:, end)); 1]));
Ac = mat2cell(As, rowDist);
end
toc
tic
for l = 1:100
D=arrayfun(@(x) A(A(:,end)==x,:), unique(A(:,end)), 'UniformOutput', false);
end
toc
tic
for l = 1:100
for k = 1:numel(e)
B{k} = A(A(:,end)==e(k),:);
end
end
toc
tic
for l = 1:100
Bb = sort(A(:,end));
[~,b] = histc(A(:,end), Bb([diff(Bb)>0;true]));
C = accumarray(b, (1:size(A,1))', [], @(r) {A(r,:)} );
end
toc
resulted in
Elapsed time is 0.053452 seconds.
Elapsed time is 0.17017 seconds.
Elapsed time is 0.004081 seconds.
Elapsed time is 0.22069 seconds.
So for even for a large matrix the loop method is still the fastest.