为什么peakutils.peak.indexes()似乎忽略了提供的阈值?

时间:2018-03-25 16:11:12

标签: python peakutils

我检索分别保存来自plt.psd()方法的信号的功率电平和频率的数组:

Pxx, freqs = plt.psd(signals[0], NFFT=2048, Fs=sdr.sample_rate/1e6, Fc=sdr.center_freq/1e6, scale_by_freq=True, color="green")

enter image description here 请忽略绿色和红色信号。只有蓝色的一个与这个问题相关。

我能够使用peakutils.peak.indexes()方法返回许多最重要的峰(蓝色信号)的X和Y坐标:

power_lvls = 10*log10(Pxx/(sdr.sample_rate/1e6))
indexes = peakutils.peak.indexes(np.array(power_lvls), thres=0.6/max(power_lvls), min_dist=120)
print("\nX: {}\n\nY: {}\n".format(freqs[indexes], np.array(power_lvls)[indexes]))

enter image description here 可以看出,坐标非常适合蓝色峰值。

我不满意的是我从peak.indexes()方法收到的峰坐标数。我希望仅返回高于某一功率电平的所有峰值的坐标,例如-25(其对于蓝色信号恰好是5个峰值)。根据peak.indexes()方法的文档,这是通过提供thres参数所需的值来完成的。

但无论我尝试thres,该方法似乎完全忽略了我的价值,而只依靠min_dist参数来确定返回的峰数。

  • 我的阈值有什么问题(我认为这意味着"高于情节的低60%"现在在我的代码中)并且如何正确指定某个功率级别(而不是百分比值)?

[编辑]

我发现显然thres参数只能在float 0和1之间取正值。 因此,通过如下稍微改变我的线,我现在可以根据需要影响返回峰的数量:

indexes = peakutils.peak.indexes(np.array(power_lvls), thres=0.4, min_dist=1)

但是这仍然让我怀疑是否有可能以某种方式将结果限制在五个最高峰(如果数量超过那个数字= 5 = 5)。

我相信以下内容会返回五个最高值:

print(power_lvls[np.argsort(power_lvls[indexes])[-5:]])

不幸的是,负值似乎被解释为我的power_lvls数组中的最高值。可以改变这一行,使得(+)10被认为高于例如-40?还是有另一种(更好的?)解决方案?

[编辑2]

这些是我得到的六个"最高"峰: enter image description here

power_lvls = 10*log10(Pxx/(sdr.sample_rate/1e6))+10*log10(8/3)
indexes = peakutils.indexes(power_lvls, thres=0.35, min_dist=1)

power_lvls_max = power_lvls[np.argsort(power_lvls[indexes])[-6:]]
print("Highest Peaks in Signal:\nX: \n\nY: {}\n".format(power_lvls_max))

在尝试了几个小时而没有任何改进之后,我开始认为这些既不是山谷也不是山峰,只是一些"随机"值?这让我相信我的argsort系列存在问题,我必须首先弄明白?!

[编辑3]

bottleneck.partition()方法似乎返回正确的值(即使它显然是以随机顺序,而不是从最左边的峰值到最右边的峰值):

import bottleneck as bn
power_lvls_max = -bn.partition(-power_lvls[indexes], 6)[:6]

enter image description here 幸运的是,峰值的顺序对于我计划用坐标做的事情并不重要。但是,我必须弄清楚如何将我现在拥有的Y值与相应的X值相匹配......

此外,虽然我现在有一个解决方案,但出于学习目的,知道我的argsort尝试出了什么问题仍然很有趣。

2 个答案:

答案 0 :(得分:0)

解决此问题的一种简单方法是在处理之前向Pxx向量添加常量(例如+50 dB)。这样你就可以避免负值峰值。处理完成后,您可以再次减去常数以获得正确的峰值。

答案 1 :(得分:0)

我想出了如何找到相应的X值并获得六个最高峰的完整坐标:

power_lvls = 10*log10(Pxx/(sdr.sample_rate/1e6))+10*log10(8/3)
indexes = peakutils.indexes(power_lvls, thres=0.35, min_dist=1)
print("Peaks in Signal 1\nX: {}\n\nY: {}\n".format(freqs[indexes], power_lvls[indexes]))
power_lvls_max = -bn.partition(-power_lvls[indexes], 6)[:6]
check = np.isin(power_lvls, power_lvls_max)
indexes_max = np.where(check)
print("Highest Peaks in Signal 1:\nX: {}\n\nY: {}\n".format(freqs[indexes_max], power_lvls[indexes_max]))

现在我有了#34;峰值过滤" (种类),我最初试图通过搞乱peakutils.peak.indexes()的thres值来实现。上面的代码给了我想要的结果: enter image description here