我有几个数据集,包含如下所示的峰簇: 你可以看到这里的主要特征是一组峰,每个簇有三个峰。我想找到那些局部峰值的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()
哪个效果相对较好,但仍然不完美。标记为的一些峰值这里的主要问题是我的信号不平滑,因此一些实际上不是我相关峰值的东西会被拾取。您可以在群集中间大约一半的杂散最大值中看到这一点,以及具有两个最大值的峰值,实际上它应该是一个。你可以看到附近的中心有一些高频最大值。我正在挑选那些,所以我在循环中添加只考虑高于某一点的值。
我担心平滑曲线实际上会使我松散一些我想要的聚集峰,因为在我的其他一些数据集中,它们更加紧密。也许我的恐惧是没有根据的,我只是误解了平滑的效果。任何帮助将不胜感激。
有没有人能解决如何挑选出“突出”的高峰?也就是说,只有那些与其他峰相比快速变大的峰值?
答案 0 :(得分:1)
从SciPy 1.1.0版开始,您还可以使用功能scipy.signal.find_peaks,该功能可让您根据其topographic prominence选择检测到的峰。此功能通常比find_peaks_cwt
更易于使用。您必须花点时间才能找到最佳下限,并将其作为值传递给prominence
,例如find_peaks(..., prominence=5)
将忽略示例中不需要的峰。这应该使您合理地接近目标。如果这还不够,您可以根据峰属性(例如可以返回的left_ / right_bases)自行选择峰。
答案 1 :(得分:0)
我还建议您使用scipy.signal.find_peaks。另一个较旧的安全备用find_peaks_cwt
的使用非常复杂。
基本上,它会在一行中完成您要查找的内容。除了lagru提到的prominence参数之外,对于您的数据,threshold
或height
参数也可能满足您的需求。
height = 40会过滤以获取您喜欢的所有峰。
突出有时很难准确地表现出来。