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

6
那么,我可能忽略了一些显而易见的事情,但我已经搜索了很多教程和文档,似乎找不到一个直接的答案。如何在Python中找到您对其进行fft的函数的频率轴(特别是在scipy库中的fft)?
我正在尝试获取原始EMG信号,对其执行带通滤波器,然后执行fft以查看剩余频率分量。但是,我不确定如何找到准确的x分量列表。当前我正在处理的特定信号以1000 Hz的采样率进行采样,共有5378个样本。
只需创建从0开始并到fft'd数据长度的线性x即可吗?我看到很多人从0到样本点乘以样本间距创建linspace。但在这种情况下,我的样本间距将是什么?它只是样本/采样率吗?还是完全不同的东西?

使用 numpy.fft.fftfreqrfftfreq(视情况而定)。 - tom10
2个回答

4

这是一个例子。

首先,要创建一个正弦波,采样间隔需要预先确定。我们将结合两个频率分别为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()

在这里输入图片描述

请注意,在幅度谱中,恢复了两个频率,而其他频率的振幅为零。振幅值分别为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]

1
我错了还是你所称的 freq_sampling1 变量不是构成信号的频率之一?你的信号采样频率应该是 6/(500-1) ... - Erik Thysell

0

一旦你将样本窗口输入FFT调用中,它将返回一个虚数点数组...返回数组的每个元素之间的频率分离由此决定。

freq_resolution =  sampling_freq / number_of_samples

第0个元素是您的直流偏移量,如果您的输入曲线平衡地跨越零交叉点,则为零... 所以在您的情况下

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之间具有相同的频率间隔,呈线性增量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接