如果我有一个数组:
A = (0,2,3,4,5,2,1,2,3,4,5,6,7,8,7,6,5,4,5,6)
可以看出有4个转折点。 (在A [4],A [6],A [13],A [17])
如何使用python返回转折点数?
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)
目前,这个系统存在缺陷,当然不是很优雅。有什么想法吗?
答案 0 :(得分:4)
如果你有numpy:
def turningpoints(lst):
dx = np.diff(lst)
return np.sum(dx[1:] * dx[:-1] < 0)
或非numpy等效版本:
def turningpoints(lst):
dx = [x - y for x, y in zip(lst[1:], lst[:-1])]
return sum(dx1 * dx2 < 0 for dx1, dx2 in zip(dx[1:], dx[:-1]))
只是为了爱一线人:
def turningpoints(lst):
return sum(x0*x1 + x1*x2 < x1*x1 + x0*x2 for x0, x1, x2 in zip(lst[2:], lst[1:-1], lst[:-2]))
但可读性在这一方面可以说是可以减少的:)
答案 1 :(得分:2)
我知道这是一个老问题,但我遇到了同样的问题,正如卡丁在Malvolio's answer的评论中所述,答案无法处理具有相同值的连续点,如{{1} }。我的实现可以解决这个问题。
虽然,它返回两个列表,其中包含最小和最大转折点的索引。
[1, 2, 3, 4, 4, 4, 3, 2, 1]
为了正确回答问题,转折点的数量计算如下:
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
答案 2 :(得分:1)
>>> def turns(L):
... answer, delta = 0, -1 if L[1]<L[0] else 1
... i = 2
... while i < len(L):
... d = -1 if L[i]<L[i-1] else 1
... if d != delta:
... answer += 1
... delta = d
... i += 1
... return answer
...
>>> L = [0,2,3,4,5,2,1,2,3,4,5,6,7,8,7,6,5,4,5,6]
>>> turns(L)
4
答案 3 :(得分:1)
你是在思考它。 “转折点”是指高于两侧或更低点的转折点。
def turningpoints(x):
N=0
for i in range(1, len(x)-1):
if ((x[i-1] < x[i] and x[i+1] < x[i])
or (x[i-1] > x[i] and x[i+1] > x[i])):
N += 1
return N
>>> turningpoints([0,2,3,4,5,2,1,2,3,4,5,6,7,8,7,6,5,4,5,6])
4
答案 4 :(得分:0)
def group_in_threes(slicable):
for i in range(len(slicable)-2):
yield slicable[i:i+3]
def turns(L):
for index, three in enumerate(group_in_threes(L)):
if (three[0] > three[1] < three[2]) or (three[0] < three[1] > three[2]):
yield index + 1
>>> list(turns([0,2,3,4,5,2,1,2,3,4,5,6,7,8,7,6,5,4,5,6]))
[4, 6, 13, 17]
>>> len(_)
4