4
$\begingroup$

I would like to know if a list has repeated consecutive values above a threshold. Lets say for this example the threshold is 5.

list={0, 0, 1, 2, 3, 3, 4, 2, 1, 2, 0, 2, 6, 7, 6, 5, 4, 3, 3, 4, 6, 2, 7, 6, 5, 3, 5, 4, 5, 2, 2, 1, 2, 4, 3, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 4, 3, 0, 1, 2}

because of the run 6, 7, 6, and 7, 6,the function should return True or 1 or some indication that consecutive values in the list are above the threshold.

If the threshold is 6 the function would yield False or 0 as there are no consecutive values above 6.

This code fails

Select[Split[list], First[#] > 5 && Length[#] > 1 &, Infinity]

The Split only works for consecutive values of the same value where I need it to split for consecutive values above a threshold.

I tried SplitBy but my pattern is incorrect.

SplitBy[list, Repeated[#] > 5 &]

I understand that neither of these functions above will give True or 1 but once the pattern is correct, taking it to the True or 1 is easy.

$\endgroup$

3 Answers 3

7
$\begingroup$

Fundamental operation:

t = 5;        
us = UnitStep[list - (t+1)];

(* {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, \
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} *)

Then look for sequential ones by any method:

us*list // Differences // FreeQ[1] // Not

MatchQ[us, {___, 1, 1, ___}]

Max @ ListConvolve[{1, 1}, us] > 1
$\endgroup$
4
  • $\begingroup$ Thank you. I'm so grateful. I would have never approached the problem in this way. I was killing myself on finding the correct pattern. $\endgroup$
    – Ray Troy
    Jan 20, 2017 at 20:50
  • $\begingroup$ you could directly use MatchQ on the list as MatchQ[list, {___, x_Integer /; x > #, y_Integer /; y > #, ___}] &@5 (I guess the above performs better though) $\endgroup$
    – george2079
    Jan 20, 2017 at 21:45
  • 1
    $\begingroup$ I think Clip[list, {t+1, t}, {0, 1}] is slightly faster than UnitStep[list - (t+1)]. $\endgroup$
    – Carl Woll
    Jan 20, 2017 at 22:08
  • $\begingroup$ @CarlWoll I don't believe that I was aware that in the second parameter of Clip min could be larger than max. However on my system UnitStep is several times faster than your Clip expression. $\endgroup$
    – Mr.Wizard
    Jan 20, 2017 at 23:02
1
$\begingroup$

For short lists we could also use SequenceSplit (new in 11.3)

f = DeleteCases[{_}] @ SequenceSplit[# - (th + 1), {_?Negative}] != {} &;

th = 5;

No repetitions above th

list = {6, 0, 0, 5, 5, 8, 0, 6};

f @ list

(* False *)

Repetition(s) above th

list = {6, 0, 0, 6, 6, 5, 5, 8, 0, 6};

f @ list

(* True *)

SequenceSplit is, however, much slower than the accepted answer

list = RandomInteger[{0, 7}, 10^6];

f @ list // RepeatedTiming

{1.445, True}

UnitStep[list - (th + 1)] // Differences // FreeQ[1] // Not // RepeatedTiming

{0.008, True}

$\endgroup$
2
  • $\begingroup$ I tried to look for a faster alternative than the accepted one, but I definitely couldn't think of anything better. Hopefully soon the Wolfram developers will improve the speed of the functions dedicated to sequences, since they are more practical and flexible. $\endgroup$ Jan 9 at 23:44
  • $\begingroup$ Yes, many functions have become much faster over the years. In the meanwhile I use the very nice and readable sequence-functions for short lists. $\endgroup$
    – eldo
    Jan 9 at 23:52
1
$\begingroup$

Grabbing the @eldo's examples, a faster version using Split is as follows:

list1 = {6, 0, 0, 5, 5, 8, 0, 6};
list2 = {6, 0, 0, 6, 6, 5, 5, 8, 0, 6};
list3 = RandomInteger[{0, 7}, 10^6];

f[list_, th_] := Module[{sp, pos},
sp = Split[list];
pos = First@FirstPosition[{_, __}]@Reverse@sp;
Length@Catenate@DeleteCases[{_}]@sp[[;; pos]] > th]

f[list1, 5]

(*False*)

f[list2, 5]

(*True*)

f[list3, 5] // RepeatedTiming

(*{0.347102, True}*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.