【问题标题】:Find all local Maxima and Minima when x and y values are given as numpy arrays当 x 和 y 值作为 numpy 数组给出时,查找所有局部最大值和最小值
【发布时间】:2015-06-26 10:12:49
【问题描述】:

我有两个数组 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]的那个。

【问题讨论】:

  • 你在用sortId=np.argsort(x); x=x[sortId]做什么?
  • 这个带有双 while 循环的解决方案将非常慢(而且我什至没有谈论 np.insert 几乎在每次迭代时重新分配 minm/nmax 数组) .有关在 numpy 中正确执行此操作的方法,请参阅 stackoverflow.com/questions/4624970/…
  • @mescalinum:我正在对 x 值进行排序,相应的索引将存储在 sortId 中。这样我就可以按顺序排列 y 值。
  • @Cleb : 我想要高峰和低谷。
  • @rth :实际上在我的数据集中,点是非常相邻的,所以你链接中提到的方法也在最大值和最小值周围给出了一些额外的点。

标签: python numpy derivative


【解决方案1】:

您根本不需要这个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]),)

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

情节是这样的;我移动了 x 值,以便它们对应于 minmmaxm) 中返回的索引:

从 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()

结果

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

请注意,现在第一个峰被排除在外,因为它的高度低于 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()

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

【讨论】:

  • ya....这很好...我下面给出的解决方案也给出了相同的答案....但问题是因为大数据集,它给出了很多极值作为你在我的第二个问题中告诉过,并建议在找到极值之前先平滑信号...顺便说一句谢谢
  • 很抱歉将其添加为评论,但不知道在搜索时如何措辞。 “平滑信号”是什么意思?你会用什么来做这件事?谢谢。
  • @datahappy:您可以搜索“smooth signal scipy”和“running average”,这应该会让您走上正轨。平滑消除了许多有助于找到实际峰值的局部极值。
  • 嗨,使用peaks, _ = find_peaks(-y) 可以得到最小值。
【解决方案2】:
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 分别包含最小值和最大值的索引。

【讨论】:

    【解决方案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
    

    【讨论】:

    • 导致 [ 7. 5. 2.] [ 6. 3. 1.]
    • 你成功运行了吗?忽略最初的技术问题,如 while 循环和重新分配,有人可以运行我的解决方案来检查它不会给出“索引超出范围”错误吗?
    • 我正在执行,错误来了。当你正在执行第三个 while 循环时,你没有检查索引绑定。再举个例子,然后尝试执行
    • 脚本当然会到达第三个while循环,如果是,python解析器会给我一条错误消息,但不是。请。将您运行以检查它的完整代码发送给我。你身边有问题。
    猜你喜欢
    • 2020-08-23
    • 1970-01-01
    • 2021-09-12
    相关资源
    最近更新 更多