在Python中,使用SciPy库可以方便地进行傅里叶变换和频率提取。
首先,我们需要导入相关的库和数据:
import numpy as np
from scipy.fft import fft, fftfreq
# 生成1000个等间距分布的时间点
t = np.linspace(0, 10, 1000, endpoint=False)
# 任意函数(这里以正弦函数为例)
y = np.sin(2*np.pi*5*t) + np.sin(2*np.pi*10*t) + np.sin(2*np.pi*15*t)
接下来,我们使用fft
函数对函数进行傅里叶变换:
# 傅里叶变换
fft_vals = fft(y)
上述代码将y
函数进行离散傅里叶变换,返回的fft_vals
数组包含了时域函数的频域表示。
如果我们想要获取与fft_vals
数组相关的频率,可以使用fftfreq
函数:
# 获取频率
freqs = fftfreq(len(y), t[1]-t[0])
上述代码中,第一个参数表示数据点的数量(即len(y)
),第二个参数表示两个数据点之间的时间差(即t[1]-t[0]
)。
现在,我们可以将变换结果和频率绘制在图表中:
import matplotlib.pyplot as plt
# 绘制函数
fig, axs = plt.subplots(2)
fig.suptitle('FFT Visualization')
axs[0].plot(t, y)
axs[0].set_xlabel('Time')
axs[0].set_ylabel('Amplitude')
# 绘制频域函数
axs[1].stem(freqs, abs(fft_vals))
axs[1].set_xlabel('Frequency in Hertz')
axs[1].set_ylabel('Magnitude')
上述代码将函数绘制在坐标轴的第一个图表区域,将傅里叶变换的结果绘制在第二个图表区域。stem
函数会绘制出每个频率点上的振幅值。
下面是一个完整的例子,它包含了上述所有代码,可以直接运行并查看结果:
import numpy as np
from scipy.fft import fft, fftfreq
import matplotlib.pyplot as plt
# 生成1000个等间距分布的时间点
t = np.linspace(0, 10, 1000, endpoint=False)
# 任意函数(这里以正弦函数为例)
y = np.sin(2*np.pi*5*t) + np.sin(2*np.pi*10*t) + np.sin(2*np.pi*15*t)
# 傅里叶变换
fft_vals = fft(y)
# 获取频率
freqs = fftfreq(len(y), t[1]-t[0])
# 绘制函数
fig, axs = plt.subplots(2)
fig.suptitle('FFT Visualization')
axs[0].plot(t, y)
axs[0].set_xlabel('Time')
axs[0].set_ylabel('Amplitude')
# 绘制频域函数
axs[1].stem(freqs, abs(fft_vals))
axs[1].set_xlabel('Frequency in Hertz')
axs[1].set_ylabel('Magnitude')
plt.show()
除了用自己的函数进行傅里叶变换,还可以使用现成的数据进行分析,比如读取一个音频文件,对它进行傅里叶变换,并提取频率信息:
import wave
# 打开wav文件
with wave.open('audio.wav', 'rb') as wav:
framerate = wav.getframerate()
# 读取采样数据
nframes = wav.getnframes()
data = wav.readframes(nframes)
signal = np.frombuffer(data, dtype=np.int16)
# 计算傅里叶变换
fft_vals = np.abs(fft(signal))
# 获取频率值
freqs = np.fft.fftfreq(signal.size, 1/framerate)
上述代码中,我们使用wave
库来读取一个wav文件,并将其转换成numpy数组。getframerate
函数会返回音频文件的采样率,getnframes
和readframes
函数会返回和读取所有的采样值。最后,我们计算函数的傅里叶变换,获取它的频率表示。