Finding consecutive data with non zero in array

Asked by edward kabanyas

edward kabanyas (view profile)

on 15 Sep 2019 at 14:49
Latest activity Edited by edward kabanyas

edward kabanyas (view profile)

on 7 Oct 2019 at 12:26
Accepted Answer by Andrei Bobrov

Andrei Bobrov (view profile)

Hi all;
I want to find consecutive data with non zero value in array. However, as long as the data with 0 value is less than 3 points, it is still considered as part of the previous data set. The data with the same length is classified into same array.
For example:
xx = [1 2 3 0 1 2 0 0 0 1 2 3 4 0 1 0 0 0 1 1 1];
The expected result
xx1 =[1 2 3 0 1 2; 1 2 3 4 0 1];
xx2=[1 1 1];
I try to find it using looping procedure but it takes only onsecutive data with non zero value and I can not find the solution for this criteria "as long as the data with 0 value is less than 3 points".
Hope some help.
Thank you.
Edward

Rik

Rik (view profile)

on 15 Sep 2019 at 15:30
Numbered variables are a bad idea. Also, it should be feasible to adapt your code to also work for the shorter runs of zeros. Can you share your code here? Attach it in an m file if it is more than about 20 lines long.
Otherwise, you could try the RunLength FEX submission by Jan to find the run lengths and continue from there.
Rik

Rik (view profile)

on 16 Sep 2019 at 7:45
Comment posted as answer by edward kabanyas:
Thank you Rik. The following is my code:
threshold = 0;
transitions = diff([0, xx > threshold, 0]);
runstarts = find(transitions == 1);
runends = find(transitions == -1) - 1;
blocks = arrayfun(@(s, e) xx(s:e), runstarts, runends, 'UniformOutput', false);
celldisp(blocks)
However, it takes only onsecutive data with non zero value and I can not find the solution for the criteria "as long as the data with 0 value is less than 3 points". Then, the cell with same size in blocks is not merged into one cell as I need above.

Release

R2013a

Answer by Andrei Bobrov

Andrei Bobrov (view profile)

on 16 Sep 2019 at 8:04
Edited by Andrei Bobrov

Andrei Bobrov (view profile)

on 5 Oct 2019 at 10:50

for R2013a (and for your data from all_data.txt)
f = fopen('all_data.txt');
Data = textscan(f,'%f %f %f %f %f %f %f','CollectOutput',1);
fclose(f);
Data = Data{:};
lo = any(Data(:,6:7) ~= 0,2);
d = find(lo);
ii = [true;diff(d) > 3];
i2 = ii([2:end,1]);
i = zeros(size(Data,1),1);
i(d(ii)) = 1;
i(d(i2) + 1) = -1;
j = cumsum(i);
jj = cumsum([false;diff(j) == 1]).*j;
out = accumarray(jj+1,(1:size(Data,1))',[],@(x){Data(sort(x),:)});
out = out(2:end);

edward kabanyas

edward kabanyas (view profile)

on 5 Oct 2019 at 1:20
It seems the following script is ok for R2013a:
m = size(T,1);
lo=any(T(:,6)~= 0,2);
d = find(lo);
ii = [true;diff(d) > 3];
i2 = ii([2:end,1]);
i = zeros(size(T,1),1);
i(d(ii)) = 1;
i(d(i2) + 1) = -1;
j = cumsum(i);
jj = cumsum([false;diff(j) == 1]).*j;
out = accumarray(jj+1,(1:m)',[],@(x){T(sort(x),:)});
out = out(2:end);
Andrei Bobrov

Andrei Bobrov (view profile)

on 5 Oct 2019 at 10:50
I'm fix.
edward kabanyas

edward kabanyas (view profile)

on 5 Oct 2019 at 15:22
Thank you very much Andrei. It is perfect, thank you again.

Rik (view profile)

on 16 Sep 2019 at 8:03

I used the mfile version of Jan's FEX submission RunLength, because I can't get my compiler to work right now. With the runlegth determined it is relatively easy to find the groups that need to be merged. Then you can still use the code you proposed to find the transitions.
xx = [1 2 3 0 1 2 0 0 0 1 2 3 4 0 1 0 0 0 1 1 1];
[a,b]=RunLength_M(xx~=0);
L= a(:)==false & b<3;%to be merged
%checks for egde cases should be perfomed here:
%-first group is a small group of zeros
%-last group is a small group of zeros
L_prev=[L(2:end);false];
L_next=[false;L(1:(end-1))];
b(L_prev)=b(L_prev)+b(L)+b(L_next);
a(L | L_next)=[];%remove merged parts
b(L | L_next)=[];%remove merged parts
x=RunLength_M(a,b);
transitions = diff([0, RunLength_M(a,b), 0]);
runstarts = find(transitions == 1);
runends = find(transitions == -1) - 1;
blocks = arrayfun(@(s, e) xx(s:e), runstarts, runends, 'UniformOutput', false);
celldisp(blocks)

edward kabanyas

edward kabanyas (view profile)

on 3 Oct 2019 at 13:50
I have some files and the file sizes are different, but I take one as an example, the sizie is 9886
Rik

Rik (view profile)

on 3 Oct 2019 at 14:13
What I meant to ask is if you were using a matrix or a vector a input. Attaching the data as a mat file would probably work best.
Rik

Rik (view profile)

on 5 Oct 2019 at 8:36
It turns out you also need to use (:) for b if your input is a column vector. I just tested this on R2011a, so it should also works on ancient releases. I'll edit my answer.
Edit: except that your example is integer only and your data isn't, which seems to be causing problems.