我对用Python在数据样本中找到正峰值和负峰值很感兴趣。
为了给你一个更好的想法,我正在考虑Matlab的findpeaks函数(https://it.mathworks.com/help/signal/ref/findpeaks.html)。
例如,当我在Matlab中进行时
[a1,peak_loc1] = findpeaks(data,"DoubleSided",'MinPeakHeight',peak_height)
我得到了峰值和峰值出现的指数。
现在,我在scipy信号find_peaks函数中找到了一个很好的候选者(https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html)。
这似乎很相似。但事实上,它并没有提供我想要的结果。事实上,它返回峰值和一个包含返回峰值属性的字典。
因此,为了返回a1和peak_loc1值,我做了一个额外的操作:
import numpy as np
from scipy.signal import find_peaks
def findpeaks(arr, h, w=1, d=1):
pos = find_peaks(arr, height=h, width=w, distance=d)
pos_list = dict(zip(pos[0], pos[1]['peak_heights']))
neg = find_peaks(arr * -1, height=h, width=w, distance=d)
neg_list = dict(zip(neg[0], neg[1]['peak_heights'] * -1))
full_list = {**pos_list, **neg_list}
full_list = dict(sorted(full_list.items()))
heights = list(full_list.values())
indexes = list(full_list.keys())
return heights, indexes
然而,我得到的结果与Matlab中的结果不匹配。
为了更容易看到差异,请看一下我将值并排放置的屏幕截图。左边是matlab的值,右边是Python的值。
数值比较
白色的值是相同的。然而,在某些情况下,Matlab的相应值会在一个位置后偏移。我用颜色突出显示了匹配的值。然后有两个值(红色(与Python计算的值没有任何对应关系。
这是我的Python代码:
请注意,数据是一个简单的np.array,但其中有大约12K的值,所以你可以在这里查看:https://pastebin.pl/view/d3d5dba4
data = *
peak_height = 0.4455
a1, peak_loc1 = findpeaks(data, peak_height)
原因是什么?我唯一想到的是缺少一些参数。。。即什么将对应于";双面"?给定"MinPeakHeight"应该是我已经传递给Python的peak_height参数。
根据使用的参数DoubleSided
和您的屏幕截图,我假设您实际上使用的是Octave的findpeaks
,而不是Matlab的!如果你阅读了参数描述:
"双面的">-告诉函数数据取正值和负值。将峰值的基线作为函数的平均值。这相当于在去除平均值后传递数据的绝对值。
因此,在检查MinPeakHeight
之前,使用DoubleSided
实际上会操纵data
中的绝对值,因此会改变哪些峰值低于或高于高度0.4455。我们可以在Python中模仿这一点(我冒昧地简化/加速了您的功能(:
def findpeaks(arr, h, w=1, d=1):
# Adjust baseline to emulate 'DoubleSided'
adjusted = arr - arr.mean()
# Only consider absolute value to find local maxima AND minima
adjusted = abs(adjusted)
indexes, _ = find_peaks(adjusted, height=h)
# Retrieve extrema heights from original signal rather
# than from the properties dict with adjusted heights
heights = arr[indexes]
return heights, indexes
a1, peak_loc1 = findpeaks(data, h=0.4455)
for h, i in zip(a1, peak_loc1):
# For display purpose, adjust index by +1
# to match Octave/Matlab's indexing
print(f"{h:>9.5f} | {i + 1:>5}")
使用data
运行此操作将打印出与Octave的输出相同的值(至少我没有发现差异(。