如何从 fft 函数获取频率轴?
How to get frequency axis from an fft function?
所以,我可能遗漏了一些明显的东西,但我已经搜索了很多教程和文档,但似乎找不到直接的答案。您如何找到您在 Python 中执行 fft 的函数的频率轴(特别是 scipy 库中的 fft)?
我正在尝试获取原始 EMG 信号,对其执行带通滤波器,然后执行 fft 以查看剩余的频率分量。但是,我不确定如何找到准确的 x 组件列表。我目前正在处理的特定信号以 1000 Hz 采样并具有 5378 个样本。
它只是创建一个从 0 开始到 fft 数据长度的线性 x 吗?我看到很多人创建一个从 0 到采样点乘以采样间距的 linspace。但是在这种情况下我的样本间距是多少?只是 samples/sampling 率吗?还是完全不同?
一旦您将 window 样本输入 FFT 调用,它将 return 一个虚点数组...returned 数组的每个元素之间的频率间隔为由
决定
freq_resolution = sampling_freq / number_of_samples
第 0 个元素是您的 DC 偏移量,如果您的输入曲线平衡跨越零交叉点,它将为零...所以在您的情况下
freq_resolution = 1000 / 5378
一般来说,为了提高效率,您需要将样本数量的 2 的偶数次方输入到 FFT 调用中,如果您说要及时向前滑动 window 样本并重复调用 FFT,这很重要每个 window
计算给定 freq_bin 中频率的大小(returned 虚构数组的一个元素)
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
之间具有相同的频率间隔
这是一个例子。
首先创建一个采样间隔为pre-determined的正弦波。我们将合并两个频率为 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()
注意图中两个正弦波是叠加的。一个有频率。 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]
所以,我可能遗漏了一些明显的东西,但我已经搜索了很多教程和文档,但似乎找不到直接的答案。您如何找到您在 Python 中执行 fft 的函数的频率轴(特别是 scipy 库中的 fft)?
我正在尝试获取原始 EMG 信号,对其执行带通滤波器,然后执行 fft 以查看剩余的频率分量。但是,我不确定如何找到准确的 x 组件列表。我目前正在处理的特定信号以 1000 Hz 采样并具有 5378 个样本。
它只是创建一个从 0 开始到 fft 数据长度的线性 x 吗?我看到很多人创建一个从 0 到采样点乘以采样间距的 linspace。但是在这种情况下我的样本间距是多少?只是 samples/sampling 率吗?还是完全不同?
一旦您将 window 样本输入 FFT 调用,它将 return 一个虚点数组...returned 数组的每个元素之间的频率间隔为由
决定freq_resolution = sampling_freq / number_of_samples
第 0 个元素是您的 DC 偏移量,如果您的输入曲线平衡跨越零交叉点,它将为零...所以在您的情况下
freq_resolution = 1000 / 5378
一般来说,为了提高效率,您需要将样本数量的 2 的偶数次方输入到 FFT 调用中,如果您说要及时向前滑动 window 样本并重复调用 FFT,这很重要每个 window
计算给定 freq_bin 中频率的大小(returned 虚构数组的一个元素)
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
之间具有相同的频率间隔这是一个例子。
首先创建一个采样间隔为pre-determined的正弦波。我们将合并两个频率为 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()
注意图中两个正弦波是叠加的。一个有频率。 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]