【问题标题】:Finding only the "prominent" local maxima of a 1d array仅查找一维数组的“突出”局部最大值
【发布时间】:2017-03-25 02:19:11
【问题描述】:

我有几个数据集的峰值簇如下所示: 您可以看到这里的主要特征是一个峰簇,每个簇有三个峰。我想找到那些局部峰值的 x 值,但我遇到了一些问题。我目前的代码如下:

import numpy as np
import matplotlib.pyplot as plt
from scipy import loadtxt, optimize
from scipy.signal import argrelmax

def rounddown(x):
    return int(np.floor(x / 10.0)) * 10

pixel, value = loadtxt('voltage152_4.txt', unpack=True, skiprows=0)

ax = plt.axes()
ax.plot(pixel, value, '-')
ax.axis([0, np.max(pixel), np.min(value), np.max(value) + 1])

maxTemp = argrelmax(value, order=5)
maxes = []
for maxi in maxTemp[0]:
    if value[maxi] > 40:
        maxes.append(maxi)

ax.plot(maxes, value[maxes], 'ro')

plt.yticks(np.arange(rounddown(value.min()), value.max(), 10))
plt.savefig("spectrum1.pdf")
plt.show()

效果相对较好,但仍不完美。一些峰值标记为: 这里的主要问题是我的信号不平滑,所以一些实际上不是我相关峰值的东西正在被拾取。您可以在集群中大约一半的杂散最大值中看到这一点,以及具有两个最大值的峰,实际上它应该是一个。您可以在图的中心附近看到一些高频最大值。我正在挑选这些,所以我在循环中添加了只考虑高于某个点的值。

我担心平滑曲线实际上会使我失去一些我想要的聚集峰,因为在我的其他一些数据集中,它们之间的距离甚至更近。不过,也许我的担心是没有根据的,我只是误解了平滑的工作原理。任何帮助将不胜感激。

有没有人能解决如何只挑出“突出”的山峰?也就是说,只有那些比其他峰快大的峰?

【问题讨论】:

  • scipy 有一个内置的峰值检测器:scipy.signal.find_peaks_cwt,它使用小波分析。
  • 噪声数据中的峰值检测并非易事,从你的结果来看,我认为你的算法已经做得很好了。一个简单的解决方案可能是实施一个规则,即两个峰必须由足够深的谷隔开。
  • 感谢两位的建议。我最终选择了 Chris 的解决方案,因为它有点“安全”,因为它很少会错过峰值。我没有意识到峰值检测并非易事,所以我对我的解决方案感到满意。
  • find_peaks_cwt 更适合我的另一种方法是手动过滤信号,首先将其与高斯窗口进行卷积,然后搜索最大值(请参阅this answer)。

标签: python numpy scipy signal-processing


【解决方案1】:

从 SciPy 版本 1.1.0 开始,您还可以使用函数 scipy.signal.find_peaks,它允许您根据 topographic prominence 选择检测到的峰。此功能通常比find_peaks_cwt 更易于使用。您必须花一点时间才能找到作为值传递给prominence 的最佳下限,但例如find_peaks(..., prominence=5) 将忽略您示例中不需要的峰值。这应该使您合理地接近您的目标。如果这还不够,您可以根据可选返回的 left_/right_bases 等峰值属性进行自己的峰值选择。

【讨论】:

    【解决方案2】:

    我还推荐scipy.signal.find_peaks 来满足您的需求。另一个较旧的 scipy 替代 find_peaks_cwt 使用起来相当复杂。

    它基本上会在一行中完成您正在寻找的事情。除了 lagru 提到的突出参数之外,对于您的数据,thresholdheight 参数也可能满足您的需求。

    height = 40 将过滤以获得您喜欢的所有峰值。

    Prominence 有时很难完全理解它的作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      • 1970-01-01
      • 2018-08-10
      相关资源
      最近更新 更多