如何从fft函数获取频率轴?

时间:2018-10-09 23:50:21

标签: python numpy fft

因此,我可能缺少明显的东西,但是我搜索了许多教程和文档,但似乎找不到直接的答案。如何找到在Python中执行fft的函数的频率轴(特别是scipy库中的fft)?

我正在尝试获取原始EMG信号,对其执行带通滤波器,然后执行fft来查看其余的频率分量。但是,我不确定如何找到准确的x组件列表。我目前正在处理的特定信号以1000 Hz采样,并有5378个采样。

是否只是创建一个从0开始到fft'd数据长度的线性x?我看到很多人在创建从0到采样点乘以采样间隔的linspace。但是在这种情况下我的样本间距是多少?只是采样/采样率?还是完全其他的东西?

2 个答案:

答案 0 :(得分:0)

将样本窗口输入FFT调用后,它将返回一个虚点数组...返回数组的每个元素之间的频率间隔由

确定
freq_resolution =  sampling_freq / number_of_samples

第0个元素是您的DC偏移量,如果您的输入曲线在零交叉点之间保持平衡,则它将为零...

freq_resolution = 1000 / 5378

通常,为了提高效率,您需要向FFT调用中馈入2个样本的偶数次幂,如果要说将采样窗口及时向前滑动并在每个窗口上重复调用FFT,则很重要

要计算给定的freq_bin(返回的虚数数组的元素)中的频率幅度

X = A + jB

    A on real axis
    B on imag axis

for above formula its

mag = 2.0 * math.Sqrt(A*A+B*B) / number_of_samples

phase  == arctan( B / A )

您遍历每个元素直到奈奎斯特极限,这就是为什么您将幅度倍增的原因

是的,它是每个freq_bin之间具有相同频率间隔的线性增量

答案 1 :(得分:0)

这里是一个例子。

首先创建一个具有预定采样间隔的正弦波。我们将结合两个频率为20和40的正弦波。请记住,如果时间间隔较长,则高频可能会混叠。

#Import the necessary packages
from scipy import fftpack
import matplotlib.pyplot as plt
import numpy as np

# sampling freq in herts 20Hz, and 40Hz
freq_sampling1 = 10
freq_sampling2 = 20
amplitude1 = 2 # amplitude of first sine wave
amplitude2 = 4 # amplitude of second sine wave
time = np.linspace(0, 6, 500, endpoint=True) # time range with total samples of 500 from 0 to 6 with time interval equals 6/500
y = amplitude1*np.sin(2*np.pi*freq_sampling1*time) + amplitude2*np.sin(2*np.pi*freq_sampling2*time)

plt.figure(figsize=(10, 4))
plt.plot(time,y, 'k', lw=0.8)
plt.xlim(0,6)
plt.show()

enter image description here

图中注意两个正弦波叠加在一起。与频率一。 10和振幅2,另一个具有频率。 20和振幅4。

# apply fft function
yf = fftpack.fft(y, time.size)

amp = np.abs(yf) # get amplitude spectrum 
freq = np.linspace(0.0, 1.0/(2.0*(6/500)), time.size//2) # get freq axis

# plot the amp spectrum

plt.figure(figsize=(10,6))
plt.plot(freq, (2/amp.size)*amp[0:amp.size//2])
plt.show()

enter image description here

在幅度频谱中注意,两个频率被恢复,而其他频率处的幅度为零。振幅值也分别是2和4。

您可以改为使用fftpack.fftfreq来获取 tom10 建议的频率轴 因此,代码更改为

yf = fftpack.fft(y, time.size)
amp = np.abs(yf) # get amplitude spectrum 
freq = fftpack.fftfreq(time.size, 6/500)
plt.figure(figsize=(10,6))
plt.plot(freq[0:freq.size//2], (2/amp.size)*amp[0:amp.size//2])
plt.show()

我们只绘制了幅度频谱[0:amp.size//2]的正部分