2

I am having some trouble with halting my iteration up until I reach a certain point in my list using Python. I have a list that looks like:

lst = [-0.5, 44, 90, 132.22, 129.6, 89, 67.91, 12.5, 11, 0.0006, 10.2, 67, 89.07, 100, 132.224, 129.88, 120.1, 100, 89.5, 75, 40, 9.8, -0.4, 0.1, 90, 99, 112, 132.22]

I've asked a question similar to this before, in which the list was in a somewhat different pattern. This time, in each experiment series, the pressure starts of low, then rises to a maximum value, and lowers again.

I would like to obtain the index and value of each start and end point for each experiment.

For instance, there are three experiments in this list. The outputs would be:

E 1:
Start: (0, -0.5) # starts at index 0, value -0.5
End: (3, 132.22)

E 2:
Start: (9, 0.0006)
End: (14, 132.224)

E 3:
Start: (22, -0.4)
End: (27, 132.22)

I am currently trying to iterate over every value; however, comparing each value against another isn't exactly helpful. For instance, I'd like to break out of the loop if a Start is found and then move forward to find the End.. Based on what I've learned so far, I am trying to do something like this:

for idx, item in enumerate(lst):
    current = item
    next = lst[(idx + 1) % len(lst)]
    if current < next:
        print(current)
    continue
    if next < current:
        print(next)
    continue

If anyone can help me modify my code or help me think about another strategy, it would help me a lot.

djennacs
  • 107
  • 1
  • 7
  • 1
    How are the end points determined? BTW, don't use `next` as a variable name, that shadows the built-in `next` function. – PM 2Ring Oct 24 '17 at 16:20
  • Is scipy or numpy solution ohk for you ? Or should it be pure python – Bharath M Shetty Oct 24 '17 at 16:20
  • @PM2Ring The first value is always the start point. The last value is determined when the next value it follows is smaller than it. Example: 129.6 (next) is smaller than 132.22 (current). So, 132.22 is marked as the end point. – djennacs Oct 24 '17 at 16:24
  • @Bharathshetty Since i'm new to Python, pure Python would be great, but I'm open to any method. – djennacs Oct 24 '17 at 16:24
  • Check my solution with your actual data do let me know the results if it works there too – Bharath M Shetty Oct 24 '17 at 16:36

2 Answers2

3

Here's a pure Python solution in the form of a generator.

def get_groups(lst):
    up = False
    for i, (u, v) in enumerate(zip(lst, lst[1:])):
        if up:
            if v < u:
                yield 'End', i, u
                up = False
        else:
            if v > u:
                yield 'Start', i, u
                up = True
    if up:
        yield 'End', i + 1, lst[-1]


lst = [-0.5, 44, 90, 132.22, 129.6, 89, 67.91, 12.5, 11, 0.0006, 10.2,
    67, 89.07, 100, 132.224, 129.88, 120.1, 100, 89.5, 75, 40, 9.8, -0.4,
    0.1, 90, 99, 112, 132.22,
]

for t in get_groups(lst):
    print(t)

output

('Start', 0, -0.5)
('End', 3, 132.22)
('Start', 9, 0.0006)
('End', 14, 132.224)
('Start', 22, -0.4)
('End', 27, 132.22)

If you don't want to process everything in the list in a loop like that you can just create the generator and then call next on it to get the next tuple from it, eg

gen = get_groups(lst)
print(next(gen))
print(next(gen))

output

('Start', 0, -0.5)
('End', 3, 132.22)

You can also do this kind of thing:

gen = get_groups(lst)
for i, (t1, t2) in enumerate(zip(gen, gen), 1):
    print(i, t1, t2)

output

1 ('Start', 0, -0.5) ('End', 3, 132.22)
2 ('Start', 9, 0.0006) ('End', 14, 132.224)
3 ('Start', 22, -0.4) ('End', 27, 132.22)
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
  • Thanks, @Bharath! Doing `zip(lst, lst[1:])` can be very handy, although there's often a cleaner solution that uses `itertools.groupby` to do the grouping for you. – PM 2Ring Oct 24 '17 at 16:45
1

One solution with scipy argrelextrema and numpy greater and less , to get both local minimas and maximas, zip to combine them i,e

from scipy.signal import argrelextrema
import numpy as np 

lst = [-0.5, 44, 90, 132.22, 129.6, 89, 67.91, 12.5, 11, 0.0006, 10.2, 67, 89.07, 100, 132.224, 129.88, 120.1, 100, 89.5, 75, 40, 9.8, -0.4, 0.1, 90, 99, 112, 132.22]
arr = np.array(lst)

#Find local minimas index, add zero in the beginning
minInd = np.insert(argrelextrema(arr, np.less),0,0)
# Find local maximas index, add the length of arr - 1 at the end 
maxInd = np.append(argrelextrema(arr,np.greater),[len(lst)-1])

# numpy indexing and zip to combine the results
end_arr = list(zip(zip(minInd,arr[minInd]),zip(maxInd,arr[maxInd])))

#Printing the output
for i in end_arr:
    print('Start :' , i[0])
    print('End:', i[1],'\n')

Start : (0, -0.5) 
End: (3, 132.22) 

Start : (9, 0.00059999999999999995)
End: (14, 132.22399999999999) 

Start : (22, -0.40000000000000002)
End: (27, 132.22) 
Bharath M Shetty
  • 30,075
  • 6
  • 57
  • 108