首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在numpy中使用FFT的频率分辨率问题

在numpy中使用FFT的频率分辨率问题
EN

Stack Overflow用户
提问于 2013-07-16 00:51:31
回答 2查看 3.9K关注 0票数 3

我使用Tektronix示波器进行一些信号采集。我得到了10.000个测量点(几个信号周期),并且我必须对这组数据进行频率分析。我的信号是8 8MHz的正弦波。当我使用SciPy或NumPy时,我得到了相同的结果-频率分布太广。两个值之间的距离为500 The,最高频率为2.5 the (荒谬)。当我想测量8 MHz左右的频率带宽时,我只能得到7.5,8.0和8.5 MHz的精确值。我试图改变由(x[1]-x[0])确定的样本间距,但没有得到更好的结果。

代码语言:javascript
复制
def CalculateFFT(t_val,p_val):
    x = t_val #Two parameters: [x,y] values
    y = lambda x: p_val
    com_signal = y(x) # Combined signal
    FFT_val = abs(scipy.fft(com_signal))
    freq_val = scipy.fftpack.fftfreq(len(com_signal), x[1]-x[0])
    spec_val = 20*scipy.log10(FFT_val)
    return freq_val, spec_val
EN

回答 2

Stack Overflow用户

发布于 2013-07-16 03:21:47

更深入地阅读DFFT的工作原理是值得的,但您应该始终牢记以下公式。对于具有n个点和最大时间Tmax的时间序列,时间分辨率由dt = Tmax /n给出

一个DFFT将产生n个点

Fmax =1/ dt

dF =1/ Tmax

你似乎建议最大频率是足够的(所以时间分辨率是可以的),但频率分辨率不够好:你需要收集更多的数据,在相同的时间分辨率。

票数 3
EN

Stack Overflow用户

发布于 2016-03-09 05:46:56

如果(1)采样时间太短,(2)您需要更高的估计频率精度,以及(3)您知道您的信号是正弦波,那么您可以将信号拟合为正弦波。与How do I fit a sine curve to my data with pylab and numpy?中类似,只是需要添加频率。

下面是一个频率约为8 MHz的示例数字:

以下是示例代码:

代码语言:javascript
复制
""" Modified from https://stackoverflow.com/a/16716964/6036470 """
from numpy import sin, linspace, pi,average;
from pylab import plot, show, title, xlabel, ylabel, subplot, scatter
from scipy import fft, arange, ifft
import scipy
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import leastsq

ff = 8e6;   # frequency of the signal
Fs = ff*128;  # sampling rate
Ts = 1.0/Fs; # sampling interval

t = arange(0,((1/ff)/128)*(128)*5,Ts) # time vector
A = 2.5;

ff_0 = 8.1456e6
y = A*np.sin(2*np.pi*ff_0*t+15.38654*pi/180) + np.random.randn(len(t))/5

guess_b = 0
guess_a = y.std()*2**0.5;
guess_c = 10*pi/180
guess_d = ff*0.98*2*pi

fig = plt.figure(facecolor="white")
plt.plot(t,y,'.', label='Signal Fred. %0.4f Hz'%(ff_0/1e6))
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.grid(alpha=0.5);

optimize_func = lambda x: (x[0]*np.sin(x[2]*t+x[1]) - y);
est_a,  est_c, est_d = leastsq(optimize_func, [guess_a, guess_c, guess_d])[0]
data_fit = est_a*np.sin(est_d*t+est_c) ;
plt.plot(t,data_fit,label='Fitted Est. Freq. %0.4f Hz'%(est_d/(2*pi)/1e6))
plt.legend()
plt.tight_layout();
plt.show();

fig.save("sinfit.png")
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17659537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档