2009-11-11 148 views
93

我可以通過找到一階導數的零交叉點或某些東西來自己寫一些東西,但它似乎是標準庫中包含的通用功能。任何人都知道嗎?Python/SciPy的峯值搜索算法

我的特定應用是一個二維數組,但通常將它用於尋找在FFT的峯值等

具體而言,在這些類型的問題,有多個強峯,然後許多較小的「峯值「只是由應該忽略的噪聲引起的。這些只是例子;不是我的實際數據:

1維峯:

FFT output with peaks

2維峯:

Radon transform output with circled peak

峯值尋找算法會發現這些峯的位置(而不僅僅是它們的值),理想情況下可以找到真正的樣本間峯值,而不僅僅是具有最大值的指數,可能使用quadratic interpolation或其他。

通常你只關心幾個強峯值,所以他們要麼被選中是因爲他們超過了一定的閾值,要麼是因爲他們是按振幅排序的有序列表的第一個峯值。

正如我所說,我知道如何自己寫這樣的東西。我只是問是否有一個預先存在的函數或包已知可以正常工作。

更新:

translated a MATLAB script和它的作品體面的1-d的情況下,但可能會更好。

更新更新:

created a better version sixtenbe爲1-d的情況。

+0

@endolith你有原始的MATLAB文件,你爲此翻譯爲Python嗎?謝謝! – Spacey 2012-03-22 23:38:02

+0

@Mohammad:http://billauer.co.il/peakdet.html https://gist.github.com/250860#file_peakdet.m – endolith 2012-03-23 14:21:48

+2

這個怎麼樣:http://docs.scipy.org/doc/scipy /reference/generated/scipy.signal.find_peaks_cwt.html – dashesy 2013-04-08 19:13:11

回答

10

我不認爲你在找什麼是由SciPy提供的。在這種情況下,我會自己編寫代碼。

樣條插值和從scipy.interpolate平滑是相當不錯的,並可能在擬合峯值,然後找到其最大值的位置相當有幫助。

2

有標準的統計功能和方法來找到數據異常值,這可能是你在第一種情況下需要的。使用衍生工具將解決你的第二個問題不過,我不確定解決連續功能和採樣數據的方法。

6

以可靠的方式檢測譜圖中的峯值已經進行了相當多的研究,例如80年代音樂/音頻信號正弦建模的所有工作。在文獻中尋找「正弦建模」。

如果你的信號和例子一樣乾淨,一個簡單的「給我一個振幅高於N個鄰居的東西」應該工作得很好。如果你有噪聲信號,一個簡單而有效的方法就是及時觀察你的峯值,並跟蹤它們:然後檢測譜線而不是譜峯。IOW,您可以在信號的滑動窗口上計算FFT,以獲得一組時間譜(也稱爲譜圖)。然後觀察譜峯在時間上的演變(即在連續的窗口中)。

+0

看看時間的高峯?檢測譜線?我不確定這是什麼意思。它會對方波起作用嗎? – endolith 2009-11-27 17:10:19

+0

我試着添加一些解釋,讓我知道如果這仍然不清楚。 – 2009-11-30 12:02:01

+0

哦,你正在談論使用STFT而不是FFT。這個問題不是專門針對FFT的;這只是一個例子。這是關於在任何一般的一維或二維陣列中找到峯值。 – endolith 2009-11-30 16:44:07

38

我在尋找類似的問題,並且我發現了一些最好的參考文獻來自化學(來自質譜數據中的峯值)。對於峯值查找算法的全面回顧,請閱讀this。這是我遇到過的峯值查找技術的最清晰的評論之一。 (小波是在嘈雜的數據中找到這種峯值的最佳選擇。)。

它看起來像你的峯值明確定義,並沒有隱藏在噪音中。在這種情況下,我建議使用平滑的savtizky-golay衍生物來尋找峯值(如果僅僅區分上面的數據,就會產生大量的誤報)。這是一種非常有效的技術,很容易實現(你需要一個矩陣類w /基本操作)。如果你只是找到第一個S-G衍生物的過零點,我認爲你會很開心。

+2

我一直在尋找一種通用的解決方案,而不是隻適用於那些特定圖像的解決方案。我改編了一個MATLAB腳本給Python,並且它工作得體。 – endolith 2009-12-17 18:30:47

+1

正確。 Matlab是算法的一個很好的來源。腳本使用什麼技術? (順便說一下,SG是一種非常通用的技術)。 – Paul 2009-12-17 21:23:50

+2

我把它鏈接到上面。它基本上只搜索大於鄰居之上某個閾值的局部最大值。當然有更好的方法。 – endolith 2009-12-18 19:35:35

14

有一個名爲scipy.signal.find_peaks_cwt在SciPy的一個函數,它聽起來就像是適合您的需求,但我沒有與它的經驗,所以我不能建議..

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

+8

是的,當我問這個問題時,這並不存在,我仍然不確定如何使用它 – endolith 2013-09-17 16:04:54

+1

你剛纔添加了這個,但是這個工作很棒。使用它很簡單。只需傳入數組和另一個數組(即.np.arange(1,10)),其中列出了您想要的所有峯寬;如果需要的話,可以篩選瘦或寬峯。再次感謝! – Miles 2015-11-03 12:56:39

10

對於那些不知道其峯值尋找算法在Python中使用,這裏的替代品的快速概述:https://github.com/MonsieurV/py-findpeaks

婉婷自己一個相當於MATLAB的findpeaks功能,我發現馬科斯·杜阿爾特的detect_peaks function是一個很好的漁獲物。

很容易使用:

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 results

1

第一件事, 「峯」 的定義是模糊的,如果沒有進一步的規範。例如,對於以下系列,你會打5-4-5一個或兩個峯嗎?

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

在這種情況下,你需要至少兩個閾值:1)高閾值僅在極限值以上才能記錄爲峯值;和2)低閾值,使得在其下面的小值所分離的極值將變成兩個峯值。

峯值檢測是極值理論文獻中一個深入研究的話題,也被稱爲「極端值的分解」。其典型應用包括基於環境變量的連續讀數識別危險事件,例如,分析風速來檢測風暴事件。