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?

 Risposta accettata

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 Commenti

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)
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
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
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)

Accedi per commentare.

Più risposte (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);

Categorie

Richiesto:

il 29 Set 2014

Commentato:

il 17 Lug 2023

Community Treasure Hunt

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

Start Hunting!

Translated by