Python scipy.signal.find_peaks_cwt返回非峰值的其他点

Python scipy.signal.find_peaks_cwt返回非峰值的其他点,python,scipy,signal-processing,Python,Scipy,Signal Processing,我正在使用scipy peakfinder查找信号中的峰值。所有的峰值都被可靠地找到,但我总是得到额外的结果(到目前为止,所有的峰值都在信号的末尾),而不是峰值。我想知道为什么会这样 下面是一个包含合成数据的完整示例: from scipy.signal import find_peaks_cwt import numpy as np import matplotlib.pyplot as plt %matplotlib inline # for jupyter notebooks x = n

我正在使用scipy peakfinder查找信号中的峰值。所有的峰值都被可靠地找到,但我总是得到额外的结果(到目前为止,所有的峰值都在信号的末尾),而不是峰值。我想知道为什么会这样

下面是一个包含合成数据的完整示例:

from scipy.signal import find_peaks_cwt
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline # for jupyter notebooks

x = np.arange(0, 15, 0.1)
y = np.sin(x)
plt.plot(y)

peakinds = find_peaks_cwt(y, np.arange(1, 5))
plt.plot(peakinds, y[peakinds], 'o')
(要在普通python shell中运行,请对
%matplotlib inline
添加注释,并在末尾添加
plt.show()

用标记为点的峰值绘制:

(最后三个点不应该在那里)

对于我的真实数据,同样的事情也会发生:

(这里最后一个点错了)


为什么会发生这种情况?

问题出在
find\u peaks\u cwt
中的
widths
参数

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

x = np.arange(0, 15, 0.1)
y = np.sin(x)
fig0 = plt.figure()
ax0 = fig0.add_subplot(111)
ax0.plot(y)

peakinds = find_peaks_cwt(y, np.arange(1, 10))  # Here changed 5 to 10
ax0.plot(peakinds, y[peakinds], 'o')
plt.axis([0, 160, -1.1, 1.1])

从:

宽度:序列 用于计算CWT矩阵的1-D宽度数组。一般来说,该范围应涵盖感兴趣峰值的预期宽度

编辑:

使用的默认小波是Ricker小波。基本上,在所有指定的
宽度下(通过调用
ricker(width[i])
)在信号和小波之间执行卷积。因此,您给出的范围必须从小(精确定位峰值)到足够大(用于检测感兴趣的峰值),但不能太大(为了避免混叠——让我们记住,小波在频域中工作)

文档摘录:算法如下:1-对提供的宽度对向量执行连续小波变换。这是向量与宽度中每个宽度的小波(宽度)的卷积

如果您通过
np.arange(10,20)
更改
宽度
,您将注意到峰值已被检测到,但其最大值未很好地定位(我们缺少精细刻度)。如果您再次尝试使用
np.arange(1,20)
,则峰值的定位效果更好

此外,如果要可视化ricker小波:

from scipy.signal import ricker
vec = ricker(100, 10)  # (nb_of_points, frequency)
fig0 = plt.figure()
ax0 = fig0.add_subplot(111)
ax0.plot(vec)
编辑2:


至于在信号末尾错误检测到的额外峰值,这很可能是由于边界效应造成的。基本上,卷积窗口超出了信号的最后一个样本。通常,对信号进行填充(零填充、信号缠绕等),但这取决于填充方式(或根本不进行填充)这种错误可能会发生。在使用这些类型的方法时,丢弃前几点和最后几点通常是合适的。

我注意到,使用宽度可以有所帮助,但我不知道如何获得可靠的值。请尝试
np.arange(1,50)
例如,第二个峰值出现两次。50应该可以,因为峰值比50宽。我对这个函数的理解有了更多的说明。希望这会有所帮助。这帮助我理解了这个函数,谢谢!但我仍然不确定如何解释实际数据图中的最后一个峰值。我使用的是
width=np.arange(5,20)
@Johannes如果没有手头的数据,很难判断……可能在信号的末尾有一些边界效果。我会自动放弃第一个和最后几个点的结果。