当x和y值作为numpy数组给出时,查找所有局部Maxima和Minima

prt*_*tkp 10 python numpy derivative

我有两个数组x,y如下:

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

我发现当地最小值和最大值的索引如下:

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++
Run Code Online (Sandbox Code Playgroud)

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

Cle*_*leb 21

你根本不需要这个while循环.下面的代码将为您提供所需的输出; 它找到所有局部最小值和所有局部最大值并分别将它们存储在minm和中maxm.请注意:将其应用于大型数据集时,请务必先将信号平滑; 否则你最终会有大量的极值.

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]),)
Run Code Online (Sandbox Code Playgroud)

这应该比上面的while循环更有效.

情节看起来像这样; 我移动了x值,使它们对应于minm和中的返回索引maxm:

在此输入图像描述

从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()
Run Code Online (Sandbox Code Playgroud)

产量

在此输入图像描述

好消息是,您现在还可以轻松设置最小峰高(例如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() 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

请注意,现在排除第一个峰值,因为它的高度低于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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

现在排除中间峰值,因为它与其他两个峰值的距离小于5.

  • 您好,可以通过使用“peaks, _ = find_peaks(-y)”来获得最小值。 (3认同)