Python/SciPy 的峰值查找算法

2025-01-22 08:45:00
admin
原创
137
摘要:问题描述:我可以通过查找一阶导数的零交叉点或其他东西自己编写一些东西,但它似乎是一个足够常见的函数,可以包含在标准库中。有人知道吗?我的特定应用是二维数组,但通常它用于查找 FFT 中的峰值等。具体来说,在这类问题中,有多个强峰值,然后有很多较小的“峰值”,这些峰值只是由应该忽略的噪声引起的。这些只是示例;不...

问题描述:

我可以通过查找一阶导数的零交叉点或其他东西自己编写一些东西,但它似乎是一个足够常见的函数,可以包含在标准库中。有人知道吗?

我的特定应用是二维数组,但通常它用于查找 FFT 中的峰值等。

具体来说,在这类问题中,有多个强峰值,然后有很多较小的“峰值”,这些峰值只是由应该忽略的噪声引起的。这些只是示例;不是我的实际数据:

一维峰值:

带峰值的 FFT 输出

二维峰值:

具有圆形峰的 Radon 变换输出

峰值查找算法会找到这些峰值的位置(而不仅仅是它们的值),理想情况下会找到真正的样本间峰值,而不仅仅是具有最大值的索引,可能使用二次插值或类似方法。

通常,您只关心几个强峰值,因此要么因为它们高于某个阈值而被选中,要么因为它们是按振幅排序的有序列表的前n 个峰值。

正如我所说,我知道如何自己编写类似的东西。我只是问是否有已知运行良好的预先存在的函数或包。

更新:

我翻译了一个 MATLAB 脚本,它在一维情况下运行良好,但可以更好。

更新更新:

sixtenbe为 1-D 情况创建了一个更好的版本。


解决方案 1:

函数scipy.signal.find_peaks,顾名思义,对此很有用。但重要的是要很好地理解其参数widththresholddistance 最重要的prominence是获得良好的峰值提取。

根据我的测试和文档,突出性的概念是“有用的概念”,用于保留好的峰值并丢弃嘈杂的峰值。

什么是(地形)突出度?它是“从山顶下降到任何较高地形所需的最小高度”,如下所示:

在此处输入图片描述

这个想法是:

突出程度越高,山峰就越“重要”。

测试:

在此处输入图片描述

我故意使用了(嘈杂的)频率变化正弦波,因为它显示出许多困难。我们可以看到,该width参数在这里不是很有用,因为如果将最小值设置得width太高,那么它将无法跟踪高频部分中非常接近的峰值。如果设置得width太低,信号的左侧部分将会出现许多不必要的峰值。同样的问题distancethreshold仅与直接邻居进行比较,这在这里没有用。prominence是提供最佳解决方案的那个。请注意,您可以组合这些参数中的许多参数!

代码:

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

x = np.sin(2*np.pi*(2**np.linspace(2,10,1000))*np.arange(1000)/48000) + np.random.normal(0, 1, 1000) * 0.15
peaks, _ = find_peaks(x, distance=20)
peaks2, _ = find_peaks(x, prominence=1)      # BEST!
peaks3, _ = find_peaks(x, width=20)
peaks4, _ = find_peaks(x, threshold=0.4)     # Required vertical distance to its direct neighbouring samples, pretty useless
plt.subplot(2, 2, 1)
plt.plot(peaks, x[peaks], "xr"); plt.plot(x); plt.legend(['distance'])
plt.subplot(2, 2, 2)
plt.plot(peaks2, x[peaks2], "ob"); plt.plot(x); plt.legend(['prominence'])
plt.subplot(2, 2, 3)
plt.plot(peaks3, x[peaks3], "vg"); plt.plot(x); plt.legend(['width'])
plt.subplot(2, 2, 4)
plt.plot(peaks4, x[peaks4], "xk"); plt.plot(x); plt.legend(['threshold'])
plt.show()

解决方案 2:

我正在研究一个类似的问题,我发现一些最好的参考资料来自化学(来自质谱数据中的峰值查找)。要全面了解峰值查找算法,请阅读此文。这是我遇到的关于峰值查找技术最清晰的评论之一。(小波最适合在嘈杂的数据中查找此类峰值。)

看起来您的峰值定义清晰,没有隐藏在噪声中。在这种情况下,我建议使用平滑的 savtizky-golay 导数来查找峰值(如果您只是区分上面的数据,您将得到一堆假阳性。)。这是一种非常有效的技术,而且非常容易实现(您确实需要一个具有基本操作的矩阵类)。如果您只是找到第一个 SG 导数的零交叉点,我想您会很高兴。

解决方案 3:

scipy 中有一个名为的函数scipy.signal.find_peaks_cwt听起来很适合您的需要,但是我没有使用过它,所以我无法推荐。

http://docs.scipy.org/doc/scipy/reference/ generated/scipy.signal.find_peaks_cwt.html

解决方案 4:

对于那些不确定在 Python 中使用哪种峰值查找算法的人,这里是替代方案的快速概述:https://github.com/MonsieurV/py-findpeaks

我想要一个与 MatLabfindpeaks函数相当的函数,我发现Marcos Duarte 的detect_peaks 函数是一个很好的选择。

相当容易使用:

import numpy as np
from vector import vector, plot_peaks
from libs import detect_peaks
print('Detect peaks with minimum height and distance filters.')
indexes = detect_peaks.detect_peaks(vector, mph=7, mpd=2)
print('Peaks are: %s' % (indexes))

这将为你带来:

detect_peaks 结果

解决方案 5:

为了检测正峰值和负峰值,PeakDetect很有帮助。

from peakdetect import peakdetect

peaks = peakdetect(data, lookahead=20) 
# Lookahead is the distance to look ahead from a peak to determine if it is the actual peak. 
# Change lookahead as necessary 
higherPeaks = np.array(peaks[0])
lowerPeaks = np.array(peaks[1])
plt.plot(data)
plt.plot(higherPeaks[:,0], higherPeaks[:,1], 'ro')
plt.plot(lowerPeaks[:,0], lowerPeaks[:,1], 'ko')

峰值检测

解决方案 6:

已经对如何可靠地检测频谱中的峰值进行了大量研究,例如 80 年代对音乐/音频信号的正弦建模的所有研究。在文献中查找“正弦建模”。

如果您的信号与示例一样干净,那么简单的“给我一个幅度高于 N 个邻居的信号”应该可以很好地工作。如果您的信号有噪声,一个简单但有效的方法是及时查看峰值并跟踪它们:然后检测频谱线而不是频谱峰值。换句话说,您在信号的滑动窗口上计算 FFT,以获得一组时间频谱(也称为频谱图)。然后您查看频谱峰值随时间的变化(即在连续窗口中)。

解决方案 7:

有标准的统计函数和方法可以查找数据的异常值,这可能是您在第一种情况下所需要的。使用导数可以解决您的第二种问题。但是,我不确定是否有一种方法可以同时解决连续函数和采样数据。

解决方案 8:

我不认为 SciPy 提供了您正在寻找的内容。在这种情况下,我会自己编写代码。

scipy.interpolate 的样条插值和平滑效果非常好,可能对拟合峰值并找到其最大值的位置非常有帮助。

解决方案 9:

首先,如果没有进一步说明,“峰值”的定义是模糊的。例如,对于以下系列,您会将 5-4-5 称为一个峰值还是两个峰值?

1-2-1-2-1-1-5-4-5-1-1-5-1

在这种情况下,您至少需要两个阈值:1)一个高阈值,只有高于该阈值的极值才会被视为峰值;2)一个低阈值,以便低于该阈值的小值分隔的极值将成为两个峰值。

峰值检测是极值理论文献中一个研究得很好的课题,也被称为“极值去聚类”。它的典型应用包括根据连续读取环境变量来识别危险事件,例如分析风速以检测风暴事件。

解决方案 10:

正如本页底部所述,峰值没有通用定义。因此,如果不引入额外的假设(条件、参数等),通用的峰值查找算法就无法工作。本页提供了一些最精简建议。以上答案中列出的所有文献都是或多或少迂回的方式来做同样的事情,所以请随意选择。

无论如何,您有责任根据您的经验和相关光谱(曲线)的属性(噪声、采样、带宽等)缩小特征需要具备的属性,以便将其归类为峰值。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2974  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1836  
  PLM(产品生命周期管理)系统在企业的产品研发、生产与管理过程中扮演着至关重要的角色。然而,在实际运行中,资源冲突是经常会遇到的难题。资源冲突可能导致项目进度延迟、成本增加以及产品质量下降等一系列问题,严重影响企业的效益与竞争力。因此,如何有效应对PLM系统中的资源冲突,成为众多企业关注的焦点。接下来,我们将详细探讨5...
plm项目管理系统   47  
  敏捷项目管理与产品生命周期管理(PLM)的融合,正成为企业在复杂多变的市场环境中提升研发效率、增强竞争力的关键举措。随着技术的飞速发展和市场需求的快速更迭,传统的研发流程面临着诸多挑战,而将敏捷项目管理理念融入PLM,有望在2025年实现研发流程的深度优化,为企业创造更大的价值。理解敏捷项目管理与PLM的核心概念敏捷项...
plm项目   47  
  模块化设计在现代产品开发中扮演着至关重要的角色,它能够提升产品开发效率、降低成本、增强产品的可维护性与可扩展性。而产品生命周期管理(PLM)系统作为整合产品全生命周期信息的关键平台,对模块化设计有着强大的支持能力。随着技术的不断发展,到 2025 年,PLM 系统在支持模块化设计方面将有一系列令人瞩目的技术实践。数字化...
plm软件   48  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用