当x和y值作为numpy数组给定时,查找所有局部最大值和最小值

2024-04-20 12:19:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个数组xy作为:

x = np.array([6, 3, 5, 2, 1, 4, 9, 7, 8])
y = np.array([2, 1, 3, 5, 3, 9, 8, 10, 7])

我发现局部极小值和极大值的指数如下:

sortId = np.argsort(x)
x = x[sortId]
y = y[sortId]
minm = np.array([])
maxm = np.array([])
while i < y.size-1:
   while(y[i+1] >= y[i]):
      i = i + 1

   maxm = np.insert(maxm, 0, i)
   i++
   while(y[i+1] <= y[i]):
      i = i + 1

   minm = np.insert(minm, 0, i)
   i++

这段代码有什么问题? 答案应该是minima = [2, 5, 7]的索引 以及maxima = [1, 3, 6]的。


Tags: 代码sizenp局部数组指数arrayinsert
3条回答

这样就行了。

Python使用+=,而不是++

在while循环中使用i之前,必须分配一些值(在本例中为0),这样初始化它以避免出错。

import numpy as np

x=np.array([6,3,5,2,1,4,9,7,8])
y=np.array([2,1,3,5,3,9,8,10,7])


sortId=np.argsort(x)
x=x[sortId]
y=y[sortId]
minm = np.array([])
maxm = np.array([])
i = 0
while i < y.size-1:
   while(y[i+1] >= y[i]):
      i+=1

   maxm=np.insert(maxm,0,i)
   i+=1
   while(y[i+1] <= y[i]):
      i+=1

   minm=np.insert(minm,0,i)
   i+=1

print minm, maxm
x=np.array([6,3,5,2,1,4,9,7,8])
y=np.array([2,1,3,5,7,9,8,10,7])

sort_idx = np.argsort(x)
y=y[sort_idx]
x=x[sort_idx]
minm=np.array([],dtype=int)
maxm=np.array([],dtype=int)
length = y.size
i=0

while i < length-1:
    if i < length - 1:
        while i < length-1 and y[i+1] >= y[i]:
            i+=1

        if i != 0 and i < length-1:
            maxm = np.append(maxm,i)

        i+=1

    if i < length - 1:
        while i < length-1 and y[i+1] <= y[i]:
            i+=1

        if i < length-1:
            minm = np.append(minm,i)
        i+=1


print minm
print maxm

minmmaxm分别包含最小和最大索引。

您根本不需要这个while循环。下面的代码将为您提供所需的输出;它将查找所有本地最小值和所有本地最大值,并将它们分别存储在minmmaxm中。请注意:当你把这个应用到大数据集时,首先要确保信号平滑,否则你将得到大量的极值。

import numpy as np
from scipy.signal import argrelextrema
import matplotlib.pyplot as plt

x = np.array([6, 3, 5, 2, 1, 4, 9, 7, 8])
y = np.array([2, 1, 3 ,5 ,3 ,9 ,8, 10, 7])

# sort the data in x and rearrange y accordingly
sortId = np.argsort(x)
x = x[sortId]
y = y[sortId]

# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.show()
maxm = argrelextrema(y, np.greater)  # (array([1, 3, 6]),)
minm = argrelextrema(y, np.less)  # (array([2, 5, 7]),)

这应该比上面的循环更有效率。

这个图看起来是这样的;我移动了x值,使它们对应于minmmaxm中返回的索引:

enter image description here

从SciPy版本1.1开始,您还可以使用find_peaks

from scipy.signal import find_peaks

peaks, _ = find_peaks(y)

# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.plot(peaks, y[peaks], "x")
plt.show()

会屈服

enter image description here

好的是,您现在还可以轻松地设置最小峰值高度(例如8):

peaks, _ = find_peaks(y, height=8)

# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.plot(peaks, y[peaks], "x")
plt.show() 

enter image description here

注意,现在第一个峰值被排除在外,因为它的高度低于8。

此外,还可以设置峰值之间的最小距离(例如5):

peaks, _ = find_peaks(y, distance=5)

# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.plot(peaks, y[peaks], "x")
plt.show()

enter image description here

现在,由于中间峰与其他两个峰的距离小于5,因此将其排除在外。

相关问题 更多 >