min max of a list

Steven Bethard steven.bethard at gmail.com
Fri May 6 14:40:26 EDT 2005


querypk at gmail.com wrote:
> Hi Steve!
> I am not sure if I was clear with my previous post .Ok let me rephrase
> it .
> 
> Assume the values list is the
> content of a histogram. Then we see that
> values = [  0,  72,   2,   4,   9,   2,   0,   0,  42,  26,   0, 282,
> 23,   0, 101, 0,   0,   0,   0,   0]
> 
>  1 is repeated 72 times, 3 -> 4 times and so on. That is the index
> would be the value repeated as many times as in the list.
> Now If we find the max and look for the adjcent index.
> 
> That is if we plot the above list as a histogram. We will have crests
> and troughs ie peaks and dips. if we find two dips then the region
> between the two dips could be a range like [0,  72,   2] .So here we
> are not looking for a zero. But if we find dips then we consider the
> regions between it as a bin and group it.
> 
> |       /\
> |  /\  /  \  /\
> | /  \/    \/  \
> |/_____________________________________
>  |----|-----|---|
>     1    2    3
> 
> so pictorially. In the above plot. If y axis is the list above. then we
> need to bin it this way.
> If I use you previous approach using the groupby then all these three
> regions will be considered as one.
> 
> Hope I am clear this time.

So you want the peaks and valleys basically.  Well, using itools.window 
from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/299529, you 
could do something like:

py> values = [0,72,2,4,9,2,0,0,42,26,0,282,23,0,101,0,0,0,0,0]
py> peaks = [i
...          for i, (v1, v2, v3) in enumerate(itools.window(values))
...          if v1 < v2 and v2 > v3]
py> peaks
[1, 4, 8, 11, 14]
py> valleys = [i
...            for i, (v1, v2, v3) in enumerate(itools.window(values))
...            if v1 >= v2 and v2 <= v3]
py> valleys
[2, 6, 7, 10, 13, 15, 16, 17, 18]
py> [(min((abs(p - v), v) for v in valleys + [0] if v < p)[1],
...   p,
...   min((abs(p - v), v) for v in valleys if v > p)[1])
...  for p in peaks]
[(0, 1, 2), (2, 4, 6), (7, 8, 10), (10, 11, 13), (13, 14, 15)]

This is not likely the most efficient approach, but it's pretty simple:
  * identify the peaks and valleys
  * identify the valley on each side of a peak

STeVe



More information about the Python-list mailing list