Python傅立叶变换
1. 什么是傅里叶变换?
在数学中,变换技术用于将函数映射到与其原始函数空间不同的函数空间。傅里叶变换时也是一种变换技术,它可以将函数从时域空间转换到频域空间。例如以音频波为例,傅里叶变换可以根据其音符的音量和频率来表示它。
我们可以说,任何函数的傅里叶变换所执行的变换都是频率的函数。其中结果函数的大小是原始函数所包含的频率的表示。
让我们举一个信号的例子,它的时域函数如下所示:
在同一时间范围内获取另一个信号的一部分
将这两个信号的称为 A(n) 和 B(n),其中 n 是时域。因此,如果我们添加这些信号,信号的结构将如下所示:
C(n) = A(n) + B(n)
可以看到,函数的信号相加是将两个信号进行了加的操作,如果我们试图从这个相加信号 C 中提取信号 A 或 B,我们会遇到一个问题,因为 这些信号只是功率相加,和时间没有关系。也就是说相加的操作是同一时间上的功率的相加。
可以在上图中看到,频域可以很容易地突出信号之间的差异。如果希望将这些信号转换回时域,我们可以使用傅里叶逆变换。
2. numpy.fft与scipy.fft
Python的numpy和scipy模块提供了数学中所需的所有转换技术,所以可以直接使用它。
下面的例子都是用的scipy,但是实际使用中如果能不用scipy尽量不用,毕竟少用一个库就少一些部署上的麻烦。
import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft, fftfreq
制作正弦波
# sample points
N = 1200
# sample spacing
T = 1.0 / 1600.0
x = np.linspace(0.0, N*T, N, endpoint=False)
sum = np.sin(50.0 * 2.0 * np.pi*x) + 0.5*np.sin(80.0 * 2.0 * np.pi*x)
plt.plot(sum)
plt.title('Sine wave')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.grid(True, which='both')
plt.show()
上面的输出中,可以看到使用 NumPy 生成的正弦波,现在可以使用 scipy 库的 FFT 模块对其进行转换。
sumf = fft(sum)
xf = fftfreq(N, T)[:N//2]
plt.ylabel('frequency')
plt.xlabel('sample')
plt.title("FFT of sum of two sines")
plt.plot(xf, 2.0/N * np.abs(sumf[0:N//2]))
plt.show()
fft输出的结果是复数,其中实部表示频率,虚部表示相机,如果只关心频率,取绝对值即可。
现在可以清楚地看到各种波的频率是多少,作为时域的函数形成的时这些并不明显,只有在频域表示时才能清楚的看到这些区别。
参考文献
主要内容来自下文,内容略有增加