5
$\begingroup$

Is there a simple way to determine the run length of elements in a list that satisfy a pattern?

For example, consider the following list:

digit={0.2,0.9,0.6,0.6,0.7,0.4,0.3,0.2}

The second element (0.9) through to the fifth element (0.7) are all greater than 0.5.

Is there a function to compute such run lengths? When I input the list(digit), it would tell me how many adjacent elements in this list are greater than 0.5?

$\endgroup$
1
  • 1
    $\begingroup$ What should be the result if there are two such subsequences, for example digit = {0.2, 0.6, 0.6, 0.1, 0.7, 0.7, 0.7, 0.1}? $\endgroup$
    – Domen
    Sep 21, 2022 at 8:04

4 Answers 4

8
$\begingroup$
digit = {0.2, 0.9, 0.6, 0.6, 0.7, 0.4, 0.3, 0.2};

SequenceSplit[digit, {_?(# <= 0.5 &)}]

{{0.9, 0.6, 0.6, 0.7}}

This example is quite small. Consider:

SeedRandom[4];
alist = Round[RandomReal[{1, 0}, 50], 0.1]

{0.7, 0.4, 0.4, 0.9, 0.2, 0.3, 0.9, 0.6, 0.1, 0.7, 0.2, 0.8, 0.1,
0.8, 0.3, 0.6, 0.8, 0.7, 0.4, 0.6, 0.5, 0.2, 0.2, 0.2, 0.2, 0.3, 0.2,
0.6, 0.3, 0.9, 0., 0.9, 0.3, 0.7, 0.6, 0.2, 0.5, 0.9, 0.6, 0.8, 0.5,
0.9, 0.7, 0.1, 0.7, 1., 0.8, 0.5, 0.7, 0.1}

SequenceSplit[alist, {_?(# <= 0.5 &)}]

Another solution is possible using SequenceCases:

SequenceCases[alist, { __?(# > 0.5 &)}]

If you have difficulty counting the length of sublists in the result below, please let me know.


Result

{{0.7}, {0.9}, {0.9, 0.6}, {0.7}, {0.8}, {0.8}, {0.6, 0.8, 0.7}, {0.6}, {0.6}, {0.9}, {0.9}, {0.7, 0.6}, {0.9, 0.6, 0.8}, {0.9, 0.7}, {0.7, 1., 0.8}, {0.7}}


For further study:

Visualizing runs of two or more items that match the pattern, along with their lengths:

SequenceReplace[alist, 
 k : { Repeated[_, {2, ∞}]?(# > 0.5 &)} :>
  {
   Style[Framed[Length@k], Red], 
   Style[Framed[k, Background -> Lighter@Lighter@Yellow]]
   }
 ]

enter image description here

$\endgroup$
4
$\begingroup$

Complementary answer:

SeedRandom[4];
alist = Round[RandomReal[{1, 0}, 50], 0.1]

Then

res = {}
Table[If[alist[[i]] >= 0.5, AppendTo[res, {i, alist[[i]]}], Nothing], {i, 1, Length[alist]}];

yields, for example,

{{1, 0.7}, {4, 0.9}, {7, 0.9}, {8, 0.6}, {10, 0.7}, ...}
$\endgroup$
1
  • $\begingroup$ From that, you can build functions such as counters, etc. $\endgroup$
    – Valacar
    Sep 21, 2022 at 8:40
2
$\begingroup$
l1 = {0.2, 0.9, 0.6, 0.6, 0.7, 0.4, 0.3, 0.2};

l2 = {0.9, 0.2, 0.9, 0.6, 0.6, 0.7, 0.4, 0.3, 0.2, 0.6, 0.7};

Grabbing the @eldo's examples and using Pick with SplitBy:

Cases[{__}]@(Pick[#, # > 0.5 & /@ #] & /@ SplitBy[l1, # > 0.5 &])

{{0.9, 0.6, 0.6, 0.7}}

Cases[{__}]@(Pick[#, # > 0.5 & /@ #] & /@ SplitBy[l2, # > 0.5 &])

{{0.9}, {0.9, 0.6, 0.6, 0.7}, {0.6, 0.7}}

The run lengths are

Length /@ %

{1, 4, 2}

$\endgroup$
1
$\begingroup$
al = {0.2, 0.9, 0.6, 0.6, 0.7, 0.4, 0.3, 0.2};

Using Split and DeleteCases

DeleteCases[{x_ /; x <= 0.5}] @ Split[al, #1 > 0.5 && #2 > 0.5 &]

{{0.9, 0.6, 0.6, 0.7}}

A more complicated list

bl = {0.9, 0.2, 0.9, 0.6, 0.6, 0.7, 0.4, 0.3, 0.2, 0.6, 0.7};

DeleteCases[{x_ /; x <= 0.5}] @ Split[bl, #1 > 0.5 && #2 > 0.5 &]

{{0.9}, {0.9, 0.6, 0.6, 0.7}, {0.6, 0.7}}

The run lengths are

Length /@ %

{1, 4, 2}

$\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.