我正在尝试编写一组简单的指令以返回一组数据中峰的索引。在我的实际数据集中,我有多个峰值(因此仅查找最大值或最小值是不够的)。出于我的目的,我可以将峰值定义为小于in中的值,也小于in中的后一个值(我正在寻找负峰)。
我有一个可行的示例,但是如果列表中有两个相同的数字,它将失败。
mylist = [10, 8, 5, 3, 1, 3, 4]
min =[]
for i in mylist[1:-1]: # the pre and post comparison means I have to start from item 2 to second last item
pre = mylist.index(i)-1
post = mylist.index(i)+1
print('current i', i)
print('index', pre, post)
print('values pre post', mylist[pre], mylist[post])
if i < mylist[pre] and i< mylist[post]:
print('true')
min.append(mylist.index(i))
print('min=', min)
这似乎一直有效,直到到达列表中的第二个“ 3”(在位置5),在这种情况下,它会根据第一个“ 3”的任一侧的值对其求值。
....
current i 1
index 3 5
values pre post 3 3
true
current i 3
index 2 4
values pre post 5 1
min= [4]
如您所见,它正确地发现'1'之后的值是'3',但我认为它基本上是说索引5处的值= 3,所以值是3的任意一边,然后读取第3个。我的头这似乎是微不足道的,但被弄糊涂了。我的搜索以及在撰写本文时提出的建议问题都没有标记任何重复项,但是如果我是这件事的第一人,我会感到惊讶...
(也用于解释,我使用的是scipy find_peaks,但不适用于我的目的。如果最终数据点上升,它将最后一个数据点识别为峰值。例如[... 11, 12, 13, 14, 15]
,它将识别“ 15'(可能不是)。
答案 0 :(得分:3)
当我尝试遍历mylist[1:-1]
由于在第一个迭代中需要前一个元素的索引,而在最后一个迭代中需要后继元素,因此代码将丢失定位某些值的错误,并且还会出现'IndexError: list index out of range
错误。
另外,您正在编写大量代码以将每次迭代的索引和值相关联,这些代码是内置在enumerate(list)函数中的
以下代码可以正常运行,并且可以满足您的需求:
mylist = [10, 8, 5, 3, 1, 3, 4]
peak = [] # min is a python keyword, so it is advised that you don't define it as a variable, we'll use peak to list all min values
# While iterating through indices and values, use enumerate
for i,x in enumerate(mylist): # iterate through all indices
if i == 0 or i == (len(mylist)-1): # pass the first and last index
pass
else:
pre = mylist[i-1] # use the index variable i to locate pre
post = mylist [i+1] # and post
print ("Selected list >> Pre: {}, Index: {}, Post: {}".format(pre,x,post)) # updated the print line to make it more readable
if pre > x < post: # check if current element is between pre and post
print ("True")
peak.append(x) # append to peak list if true
print (peak)
[Out]:
Selected list >> Pre: 10, Index: 8, Post: 5
Selected list >> Pre: 8, Index: 5, Post: 3
Selected list >> Pre: 5, Index: 3, Post: 1
Selected list >> Pre: 3, Index: 1, Post: 3 # Peak found
True # Print true
Selected list >> Pre: 1, Index: 3, Post: 4
[1] # only 1 peak in the list
让我知道您是否对代码感到满意。
答案 1 :(得分:0)
如果您愿意使用numpy和scipy,则可以在numpy数组上使用scipy.argrelextrema
来获取局部最小值(在https://stackoverflow.com/a/13491866/3651127之后):
import numpy as np
from scipy.signal import argrelextrema
mylist = [10, 8, 5, 3, 1, 3, 4]
x = np.array(mylist)
# for local minima
argrelextrema(x, np.less)
返回:
(array([4], dtype=int64),)