Finding consecutive data with non zero in array
17 次查看(过去 30 天)
显示 更早的评论
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
2 个评论
Rik
2019-9-15
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
2019-9-16
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.
采纳的回答
Andrei Bobrov
2019-9-16
编辑:Andrei Bobrov
2019-10-5
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);
10 个评论
更多回答(1 个)
Rik
2019-9-16
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)
5 个评论
Rik
2019-10-3
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
2019-10-5
编辑:Rik
2019-10-5
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.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Multidimensional Arrays 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!