Collapsing data that are within one integer value of each other

1 view (last 30 days)
So I've run in to a problem utilizing the zeros generated from using fnzeros. I am able to condense down these zero points, but I need them condensed even more. Basically, there are multiple points in this 1x40 array that are within 1 integer value of each other (19, 20, 21...etc.). They are sometimes groups of 3, but also groups of 2 values which are within 1 integer value of each other. Because of this, if I try to index in steps such as 1:2:length(z) then it will get rid of points that I need. My goal is if there are three values i.e. 19,20,21 then the average is kept (20) and if there are two values then one number is kept i.e. 673,674 will keep 674. I have thought about utilizing logical indexes or possibly sorting the data and then trying to remove the values, but am having trouble figuring out the proper way to do this. I know that since it is a small 1x40 array that I can manually pluck out the data points, but this is very inefficient.
z =
19 20 21 136 382 631 673 674 760 761 762 877 1124 1372 1414 1415 1501 1502 1503 1618 1865 2113 2155 2156 2242 2243 2244 2360 2606 2854 2896 2897 2983 2984 2985 3100 3347 3595 3637 3638
inx = 1:length(SA);
sp = spline(inx,SA);
z = fnzeros(sp);
z = round(z(1,:));

Accepted Answer

Andrei Bobrov
Andrei Bobrov on 3 Jul 2018
Edited: Andrei Bobrov on 3 Jul 2018
n = diff(z(:)) == 1;
lo = [n;0] | [0;n];
nn = [diff([0;n]) == 1;0];
nn(~lo) = 1;
out = ceil(accumarray(cumsum(nn),z(:),[],@mean));
  1 Comment
Michael Jacobson
Michael Jacobson on 3 Jul 2018
Wow, this code works perfectly! I have been reading through the documentation to try and understand it completely. Here's my attempt at explaining it:
-n is the initial logical index that uses diff to track numbers that are within one integer previous of each element
-lo is another logical index that accounts for the fact that the function diff will skip over the first element in the array
-nn = [diff([0;n]) == 1;0]; Not quite sure what exactly is happening with this line. I know a vector is generated from a logical index here.
- This line is setting all nn values in cells which do not equal lo to the value 1
- Reading over the documentation for these functions. accumarray is applying the everage to each subset of elements in z that have identical subscripts in cumsum(nn). cumsum(nn) returns the cumulutive sum of nn. ceil rounds each element to the nearest integer greater than or equal to that element.
Thank you very much Andrei ! If you can help explain your code to me that would be even more helpful. I truly do enjoy learning.

Sign in to comment.

More Answers (0)

Categories

Find more on Spline Postprocessing 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!