Splitting a vector up into unequal sections seperated by zeros

13 views (last 30 days)
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
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
Star Strider
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
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)

Sign in to comment.

More Answers (1)

Michael Haderlein
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

Community Treasure Hunt

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

Start Hunting!