Splitting a vector up into unequal sections seperated by zeros

Hi everyone
I was wondering if someone could help me split up a vector into sections seperated by zeros. I have alot of data but if I give you an example with shorter data
if I have A = [ 1 2 3 0 0 0 0 0 2 3 4 0 0 0 0 0 4 5 6 7 0 0 0 0 1 1 1] and I would like section 1 = [ 1 2 3] section 2 = [ 2 3 4] section 3 = [ 4 5 6 7] section 4 = [ 1 1 1] how would I go about this?

 Respuesta aceptada

This works:
A = [1 2 3 0 0 0 0 0 2 3 4 0 0 0 0 0 4 5 6 7 0 0 0 0 1 1 1];
ne0 = find(A~=0); % Nonzero Elements
ix0 = unique([ne0(1) ne0(diff([0 ne0])>1)]); % Segment Start Indices
ix1 = ne0([find(diff([0 ne0])>1)-1 length(ne0)]); % Segment End Indices
for k1 = 1:length(ix0)
section{k1} = A(ix0(k1):ix1(k1));
end
celldisp(section) % Display Results

19 comentarios

Just wanted to check; if I wanted then to also include the zeros so like section 2 would be 0 0 0 0 0 and section 3 then would be 2 3 4 how would I modify to do this also?
The data to do so is already there. you'll have to include into the for loop to look at ix1(k1)+1:ix0(k1+1)-1
or build the indexing as such
isect = sort([ix0 ix1+1])
for k1 = 1:length(isect)-1
section{k1} = A(isect(k1):isect(k1+1)-1);
end
celldisp(section)
Star Strider
Star Strider el 29 de Sept. de 2014
Editada: Star Strider el 29 de Sept. de 2014
Thank you, Joseph!
Thank you so much both! This solution works very weel int he case above. I was wondering if you could help me with one thing though. As I mentioned above my actual dataset is bigger and when I try to tuse this code I get the following error;
??? Error using ==> horzcat CAT arguments dimensions are not consistent.
Oh I should also mention the error is related to the following line; ix0 = unique([ne0(1) ne0(diff([0 ne0])>1)]);
What does your actual dataset look like? What are its dimensions?
If you have a matrix and you want to analyse each row, you have to add a separate loop for each row, and add a second index to ‘section’ to account for it.
So i take it A is a mx1 array then? in that case any concatenation in the above sample would need to be converted to take into account that you're working in a mx1.
basically any concatenation like
ix0 = unique([ne0(1) ne0(diff([0 ne0])>1)]);
would need to be converted to
ix0 = unique([ne0(1);ne0(diff([0;ne0])>1)]);
otherwise convert A into 1xm array.
Yes I realised it was a problem and so I took the transform so I let A = A'; and now my matrix is of the right dimensions! Sorry I should have spotted this silly mistake before asking! THANKS GUYS!
the only other error with my actual dataset which is 7000 point btw is that it says;
??? Index exceeds matrix dimensions.
Error in ==> overallplot at 55 section{k1} = A(isect(k1):isect(k1+1)-1);
With only that information, I cannot determine what the problem is.
Perhaps you need to limit the ‘k1’ counter to something like:
for k1 = index1:index2-1
or something similar.
That’s the best I can guess.
Well thank you so much for trying to figure it out for me. Just to give you a bit more info at the moment I am using the code;
ne0 = find(ABSXX2~=0); % Nonzero Elements
ix0 = unique([ne0(1) ne0(diff([0 ne0])>1)]); % Segment Start Indices unique gives values with no repetitions
ix1 = ne0([find(diff([0 ne0])>1)-1 length(ne0)]); % Segment End Indices
isect = sort([ix0 ix1+1]);
for k1 = 1:length(isect)-1
section{k1} = A(isect(k1):isect(k1+1)-1);
end
celldisp(section)
Where ABSXX2 is 1x7000 vector
Star Strider
Star Strider el 29 de Sept. de 2014
Editada: Star Strider el 29 de Sept. de 2014
Change your ‘isect’ assignment to:
isect = sort([ix0 ix1]);
That will solve the ‘index exceeds matrix dimensions’ error.
Unfortunately I still get the following error;
??? Index exceeds matrix dimensions.
Error in ==> overallplot at 55 section{k1} = A(isect(k1):isect(k1+1)-1);
I don’t have your ‘ABSXX2’ vector, so I can’t offer suggestions. Both my original code and your revision (using ‘isect’) work on the ‘A’ vector you supplied.
I have attached an example of the matricies I am using. I am no longer getting my inital error and instead what i notice is that the sections are not split up properly and numbers are creeping into the zero section
sorry below is the data set
Star Strider
Star Strider el 30 de Sept. de 2014
Editada: Star Strider el 30 de Sept. de 2014
I haven’t seen the attachment yet. Took a break, then came back to this, adding leading and trailing zeros to ‘A’ as well, since I discovered that those crashed my previous code. They don’t crash this version.
This works, producing ‘pure’ non-zero and zero sections:
A = [0 0 1 2 3 0 0 0 0 0 2 3 4 0 0 0 0 0 4 5 6 7 0 0 0 0 1 1 1 0 0 0];
ne0 = find(A~=0); % Nonzero Elements
ix0 = unique([ne0(1) ne0(diff([0 ne0])>1)]); % Non-Zero Segment Start Indices
eq0 = find(A==0); % Zero Elements
ix1 = unique([eq0(1) eq0(diff([0 eq0])>1)]); % Zero Segment Start Indices
ixv = sort([ix0 ix1 length(A)]); % Consecutive Indices Vector
for k1 = 1:length(ixv)-1
section{k1} = A(ixv(k1):ixv(k1+1)-1);
end
celldisp(section)
I ended up duplicating the index calculations for the non-zero segments to find the zero segments as well. This was an interesting problem!
EDIT — Just now saw ‘matrix A.mat’. My current code processed it without errors. (I displayed a few sections of it and the original matrix to be sure.) The only changes to my code to run it were to replace the original ‘A’ assignment with:
matA = load('matrix A.mat');
A = matA.ABSXX2;
since it is easier than changing the two references to ‘A’.
Hello,
Your code helped me a lot, but it doesn't treat well the last section. I propose this code, which, I believe, covers all possible cases without error.
A = [0 0 1 2 3 0 0 0 0 0 2 3 4 0 0 0 0 0 4 5 6 7 0 0 0 0 1 1 1 0 0 0];
ne0 = find(A~=0); % Nonzero Elements
if ~isempty(ne0)
ix0 = unique([ne0(1) ne0(diff([0 ne0])>1)]); % Non-Zero Segment Start Indices
else
ix0 = [];
end
eq0 = find(A==0); % Zero Elements
if ~isempty(eq0)
ix1 = unique([eq0(1) eq0(diff([0 eq0])>1)]); % Zero Segment Start Indices
else
ix1 = [];
end
ixv = sort([ix0 ix1]); % Consecutive Indices Vector
section = cell(1, length(ixv));
for k1 = 1:length(ixv)
if k1 ~= length(ixv)
section{k1} = A(ixv(k1):ixv(k1+1)-1);
else
section{k1} = A(ixv(k1):length(A));
end
end
celldisp(section)

Iniciar sesión para comentar.

Más respuestas (1)

Not sure if this question is finally answered as Bran seems to still struggle with an error. Anyway, I just wanted to mention this little workaround with strings:
c=cellfun(@abs,strsplit(char(A),char(0)),'uniform',false);

Categorías

Más información sobre Matrices and Arrays en Centro de ayuda y File Exchange.

Preguntada:

el 29 de Sept. de 2014

Comentada:

el 17 de Jul. de 2023

Community Treasure Hunt

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

Start Hunting!

Translated by