Splitting a matrix based on certain values in the rows

I have a matrix A like this:
A = [911 911;
0 2;
8 5;
7 3;
911 911;
5 3;
1 6;
6 7;
911 911;
3 5;
8 4];
I want to split the matrix A into three matrices (A1,A2,A3) based on the row values 911 like this:
A1 = [0 2; 8 5; 7 3];
A2 = [5 3; 1 6; 6 7];
A3 = [3 5; 8 4];
I need to do this thing inside a for loop which will give the spitted matrix one after another.

3 Commenti

Stephen23
Stephen23 il 19 Feb 2019
Modificato: Stephen23 il 19 Feb 2019
Using numbered variables is a sign that you are doing something wrong.
Accessing variable names dynamically is one way that beginners force themselves into writing slow, complex, obfuscated buggy code that is hard to debug. Read this to know why:
You should use indexing instead. Indexing is simple, neat, and very efficient.
This is just a dummy. It can be A, B,C or any other name.
@Atta: A,B,C, ... suffers from exactly the same problems as A1, A2, A3, ... With using a cell array and and index, the code is fast and flexibel. You can e.g. simply run it for 12'781'986 rows without getting mad while typing the code with manually hidden names of variables.

Accedi per commentare.

 Risposta accettata

Stephen23
Stephen23 il 19 Feb 2019
Modificato: Stephen23 il 19 Feb 2019
No loop required:
>> idx = cumsum(all(A==911,2));
>> row = 1:numel(idx);
>> fun = @(r){A(r(2:end),:)};
>> C = accumarray(idx,row(:),[],fun);
>> C{:}
ans =
0 2
8 5
7 3
ans =
5 3
1 6
6 7
ans =
3 5
8 4

4 Commenti

But i need a loop and the resulted A1, A2 and A3 should be matrices.
"But i need a loop..."
Why?
"... and the resulted A1, A2 and A3 should be matrices."
They already are. Here is the first matrix:
>> C{1}
ans =
0 2
8 5
7 3
>> ismatrix(C{1})
ans = 1
>> isnumeric(C{1})
ans = 1
Mr. 206
Mr. 206 il 20 Feb 2019
Modificato: Mr. 206 il 20 Feb 2019
Thanks, I got it.
I just need another help, I have another 5 by 6 matrix (say D). I want to pad the matrices C{1}, C{2} and C{3} by some random number, so that the row numbers are equal.
For example, C{3} has 2 rows, so i need to put three e.g 911911 value at the bottom to make the row number equal to matrix D (5 by 6)
% Pad each cell with rows of 911,
% so that it has the same number of rows as D
% using CELLFUN with an anonymous padding function using REPMAT
C2 = cellfun(@(m) [m ; repmat(911, size(D,1)-size(m,1),size(m,2))], C)

Accedi per commentare.

Più risposte (1)

Jan
Jan il 19 Feb 2019
Modificato: Jan il 19 Feb 2019
A = [911 911;
0 2;
8 5;
7 3;
911 911;
5 3;
1 6;
6 7;
911 911;
3 5;
8 4];
index = [find(A(:, 1) == 911); size(A, 1) + 1];
n = numel(index) - 1;
Result = cell(1, n);
for k = 1:n
Result{k} = A(index(k):index(k+1)-1, :); % [EDITED]
end

2 Commenti

It's throwing an error, like "error: A(I,J): row index out of bounds; value 12 out of bound 11"
@Atta: Yes, I had a typo in my code. It is fixed now. Sometimes I expect the readers to fix bugs, when they are not too hard.
The result is a cell array and you access it as Result{1}. This is much smarter than hiding an index in the name of a variable.

Accedi per commentare.

Categorie

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by