If I for example have an array:
A = (0,2,3,4,5,2,1,2,3,4,5,6,7,8,7,6,5,4,5,6)
It can be seen that there are 4 turning points. (at A[4],A[6], A[13], A[17])
How can I use python to return the number of turning points?
import numpy as np
import scipy.integrate as SP
import math
def turningpoints(A):
print A
N = 0
delta = 0
delta_prev = 0
for i in range(1,19):
delta = A[i-1]-A[i] #Change between elements
if delta < delta_prev: #if change has gotten smaller
N = N+1 #number of turning points increases
delta_prev = delta #set the change as the previous change
return N
if __name__ == "__main__":
A = np.array([0,2,3,4,5,2,1,2,3,4,5,6,7,8,7,6,5,4,5,6])
print turningpoints(A)
Currently, this system is flawed and certainly not very elegant. Any ideas?
I know it's an old question, but I just had the same problem and as Cardin stated in the comments of Malvolio's answer, the answer cannot handle successive points with the same value like [1, 2, 3, 4, 4, 4, 3, 2, 1]
. My implementation can handle this problem.
Although, it returns two lists with the indices of the minimum and maximum turning points.
def turning_points(array):
''' turning_points(array) -> min_indices, max_indices
Finds the turning points within an 1D array and returns the indices of the minimum and
maximum turning points in two separate lists.
'''
idx_max, idx_min = [], []
if (len(array) < 3):
return idx_min, idx_max
NEUTRAL, RISING, FALLING = range(3)
def get_state(a, b):
if a < b: return RISING
if a > b: return FALLING
return NEUTRAL
ps = get_state(array[0], array[1])
begin = 1
for i in range(2, len(array)):
s = get_state(array[i - 1], array[i])
if s != NEUTRAL:
if ps != NEUTRAL and ps != s:
if s == FALLING:
idx_max.append((begin + i - 1) // 2)
else:
idx_min.append((begin + i - 1) // 2)
begin = i
ps = s
return idx_min, idx_max
To correctly answer the question, the number of turning points is then computed as:
sum(len(x) for x in turning_points(X))