好的,看来这必须通过数据分析来解决。我会提出以下步骤:
如果您怀疑数据过于嘈杂,请对数据进行预处理。我建议使用移动平均滤波器 (sp.convolve(data, sp.ones(n)/n, "same")) 或更好的 savitzky-golay-filter (sp.signal.savgol_filter(data, n, polyorder=3)),因为您会对数据的极值感兴趣,这将被 ma 滤波器不必要地扭曲。在此阶段,您可能还想消除 60Hz 噪声等伪影。
如果您感兴趣的信号处于窄带中,则频谱将是一个明显的峰值。在这种情况下,您可以只为您的数据拟合一条曲线,在这种情况下,高斯将是合适的。
import scipy as sp
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
freq, pow = read_in_your_data_here()
freq, pow = sp.asarray(freq), sp.asarray(pow)
def gauss(x, a, mu, sig):
return a**sp.exp(-(x-mu)**2/(2.*sig**2))
(a, mu, sig), _ = curve_fit(gauss, freq, pow)
fitted_curve = gauss(freq, a, mu, sig)
plt.plot(freq, pow)
plt.plot(freq, fitted_curve)
plt.vlines(mu, min(pow)-2, max(pow)+2)
plt.show()
center_idx = sp.absolute(freq-mu).argmin()
pow_center = pow[center_idx]
pow_3db = pow_center - 3.
def interv_from_binvec(data):
indicator = sp.convolve(data, [-1,1], "same")
return indicator.argmin(), indicator.argmax()
passband_idx = interv_from_binvec(pow > pow_3db)
passband = freq[passband_idx[0]], freq[passband_idx[1]]
这与其说是一个解决方案,不如说是一个示例,并且很大程度上依赖于您正在搜索并找到具有窄带的高 SNR 信号的假设。通过使用混合模型,它可以扩展到处理多个信号。