Splitting a vector up into unequal sections seperated by zeros
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
0 votes
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?
Accepted Answer
Star Strider
on 29 Sep 2014
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 Comments
Bran
on 29 Sep 2014
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?
Joseph Cheng
on 29 Sep 2014
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
Joseph Cheng
on 29 Sep 2014
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
on 29 Sep 2014
Edited: Star Strider
on 29 Sep 2014
Thank you, Joseph!
Bran
on 29 Sep 2014
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.
Bran
on 29 Sep 2014
Oh I should also mention the error is related to the following line; ix0 = unique([ne0(1) ne0(diff([0 ne0])>1)]);
Star Strider
on 29 Sep 2014
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.
Joseph Cheng
on 29 Sep 2014
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.
Bran
on 29 Sep 2014
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!
Bran
on 29 Sep 2014
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);
Star Strider
on 29 Sep 2014
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.
Bran
on 29 Sep 2014
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
on 29 Sep 2014
Edited: Star Strider
on 29 Sep 2014
Change your ‘isect’ assignment to:
isect = sort([ix0 ix1]);
That will solve the ‘index exceeds matrix dimensions’ error.
Bran
on 29 Sep 2014
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);
Star Strider
on 29 Sep 2014
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.
Bran
on 29 Sep 2014
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
Bran
on 30 Sep 2014
sorry below is the data set
Star Strider
on 30 Sep 2014
Edited: Star Strider
on 30 Sep 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’.
Adam
on 17 Jul 2023
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)
More Answers (1)
Michael Haderlein
on 29 Sep 2014
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);
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)