使用NumPy进行傅里叶变换:基础概念与实践应用

简介: 使用NumPy进行傅里叶变换:基础概念与实践应用

在数据分析和信号处理领域,傅里叶变换是一种不可或缺的工具,它能够将信号从时域转化为频域,揭示出信号内在的频率成分。在Python科学计算生态中,NumPy作为基础的数值计算库,提供了对傅里叶变换的强大支持。本文将深入浅出地介绍如何使用NumPy执行快速傅里叶变换(Fast Fourier Transform, FFT),并展示一些实际应用案例。一、傅里叶变换简介傅里叶变换是一种数学上的分析工具,它将一个函数(或信号)从时域(或空间域)转换到频域,揭示了函数或信号的不同频率成分及其相对强度。这个概念最初由法国数学家约瑟夫·傅里叶提出,经过不断发展,现在已经成为物理学、工程学、计算机科学、信号处理、图像处理等领域的重要基石。傅里叶变换的基本思想:任何一个满足一定条件的连续或离散信号,无论多么复杂,都可以表示为一组正弦波(或余弦波)的叠加。傅里叶变换就是找到这组正弦波的具体参数——频率、幅度和相位,从而将原信号分解为其频率成分的组合。连续傅里叶变换(Continuous Fourier Transform,CFT)的公式定义如下:对于一个连续时间信号 �(�)f(t),它的傅里叶变换为F(ω

fd0d6a5c4b6f3a8ab760adaec92a8ae5.png

其中,j 是虚数单位,ω 是角频率,t 是时间变量。

离散傅里叶变换(Discrete Fourier Transform,DFT)应用于离散信号,其公式定义如下:对于一个有限长的离散信号序列x[n] �[�],其DFT为 X[k]

3a21dd3a2e8abe827b59b9f13de641bd.png

其中,N 是信号序列的长度,k 是频率索引,n 是时间索引。

快速傅里叶变换(Fast Fourier Transform,FFT)是一种高效计算DFT的算法,极大地降低了计算复杂度。傅里叶变换的主要性质和应用包括:

  • 频谱分析:识别信号中的基频和谐波成分,分析噪声分布。
  • 信号滤波:在频域中对信号进行过滤,去除不需要的频率成分。
  • 信号压缩和编码:利用信号的频域特性进行数据压缩,例如在音频和视频编码中。
  • 图像处理:通过对图像进行傅里叶变换,可以实现图像的频率域滤波、图像去噪和图像压缩等任务。

二、NumPy中的傅里叶变换NumPy通过numpy.fft模块提供了一系列的傅里叶变换函数,我们可以轻松地进行傅里叶变换。举一个简单的例子,用FFT求下式的离散傅里叶变换。

4c89026a9c2aa4d312ee32e4f2946b86.png


import numpy as npimport matplotlib.pyplot as plt
# 创建一个离散时域信号t = np.linspace(0, 1, 1000, endpoint=False)f_t = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 10 * t)
# 计算离散傅里叶变换(DFT)f_k = np.fft.fft(f_t)
# DFT的结果实际上包含了负频率部分,但我们通常只关心0到采样率一半的频率范围# 所以我们只取前半部分,并且因为对称性,我们还可以除以2N_half = len(f_k) // 2xfrequencies = np.arange(N_half) * 1000 / len(t)  # 频率轴
# 取绝对值以得到幅度谱amplitudes = abs(f_k[:N_half]) / len(t)
# 绘制结果plt.figure(figsize=(12, 6))plt.subplot(2, 1, 1)plt.title("Time Domain Signal")plt.plot(t, f_t)plt.xlabel("Time (s)")plt.ylabel("Amplitude")
plt.subplot(2, 1, 2)plt.title("Frequency Domain Signal")plt.stem(xfrequencies, amplitudes)plt.xlabel("Frequency (Hz)")plt.ylabel("Amplitude")#plt.xlim(0,500)
plt.tight_layout()plt.show()

这里np.fft.fft()返回的是信号的离散傅里叶变换结果,其长度与原信号相同,但包含了正负频率分量。运行结果为:

fbee31dc321a092e2cfa8f005d5b2ac6.png

三、理解FFT结果1.  幅度谱:通常关注的是幅度信息,可以通过np.abs()获取各频率分量的幅度值。

amplitudes = np.abs(fft_result)/len(t)

2. 频率轴调整:由于FFT的结果默认是对半区间频率分布,若要获得实际对应的频率,需要根据采样率和样本点数进行调整。


# DFT的结果实际上包含了负频率部分,但我们通常只关心0到采样率一半的频率范围# 所以我们只取前半部分,并且因为对称性,我们还可以除以2N_half = len(f_k) // 2xfrequencies = np.arange(N_half) * 1000 / len(t)  # 频率轴

从图中,我们可以看到模拟信号中的两个频率值f=5和f=10,已全部显示在FFT后的图谱中四、多维傅里叶变换NumPy同样支持二维及更高维度的数据进行傅里叶变换,例如图像数据:


import numpy as npimport matplotlib.pyplot as pltfrom PIL import Image
# 加载图像并转为灰度image=Image.open("Lenna.png").convert("L")
# 对图像进行归一化处理image=np.array(image)/255.0
# 计算二维傅里叶变换ft_image = np.fft.fft2(image)
# 取其幅度谱(通常在显示频谱时,我们只关心幅度而非相位)magnitude_spectrum = np.abs(ft_image)
# 对幅度谱取平方根以改善视觉效果magnitude_spectrum_sqrt = np.sqrt(magnitude_spectrum)
# 将结果转换回uint8以便于显示magnitude_spectrum_sqrt_uint8 = ((20 * magnitude_spectrum_sqrt / magnitude_spectrum_sqrt.max()).astype(np.uint8))
# 显示原图像和其幅度谱fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs[0].imshow(image, cmap='gray')axs[0].set_title('Original Image')
axs[1].imshow(magnitude_spectrum_sqrt_uint8, cmap='gray')axs[1].set_title('Magnitude Spectrum')
for ax in axs:    ax.set_axis_off()
plt.show()

1614588e29c70b8bac0c6894583c762a.png

Lenna经过FFT后全黑了 五、结语本期,我们通过NumPy对各种类型的数据进行傅里叶变换,无论是单维时间序列数据还是多维图像数据,都能利用这一强大工具来洞察其背后的频率特性,从而服务于诸如滤波、去噪、特征提取等多种实际场景。在科学研究和工程实践中,掌握和灵活运用NumPy中的傅里叶变换功能具有重要意义。

相关文章
|
定位技术 Python
PowerShell批量修改、替换大量文件的文件名
PowerShell批量修改、替换大量文件的文件名
893 1
|
机器学习/深度学习 数据采集 人工智能
深度学习之稳健的模型推理与不确定性建模
基于深度学习的稳健模型推理与不确定性建模,是现代AI系统中至关重要的研究方向。随着深度学习在各类应用中的成功,如何保证模型在面对未知或不确定性输入时仍能做出稳健的推理,并能够量化这种不确定性,成为关键问题。稳健性与不确定性建模可以提高模型的安全性、可靠性,尤其在自动驾驶、医疗诊断等高风险领域。
930 0
`scipy.signal`模块是SciPy库中的一个子模块,它提供了信号处理、滤波、频谱分析等功能。这个模块包含了许多用于信号处理的函数和类,其中`butter()`和`filtfilt()`是两个常用的函数。
`scipy.signal`模块是SciPy库中的一个子模块,它提供了信号处理、滤波、频谱分析等功能。这个模块包含了许多用于信号处理的函数和类,其中`butter()`和`filtfilt()`是两个常用的函数。
|
存储 关系型数据库 MySQL
携程面试:100 亿分库分表 如何设计? 核弹级 16字真经, 让面试官彻底 “沦陷”,当场发offer!
携程面试:100 亿分库分表 如何设计? 核弹级 16字真经, 让面试官彻底 “沦陷”,当场发offer!
携程面试:100 亿分库分表 如何设计?  核弹级 16字真经, 让面试官彻底 “沦陷”,当场发offer!
|
算法 Go 计算机视觉
【YOLO系列】YOLOv8算法(尖端SOTA模型)
Ultralytics YOLOv8 是由 Ultralytics开发的一个前沿 SOTA 模型。它在以前 YOLO 版本的成功基础上,引入了新的功能和改进,进一步提升了性能和灵活性。YOLOv8 基于快速、准确和易于使用的理念设计,使其成为广泛的物体检测、图像分割和图像分类任务的绝佳选择。
3876 0
【YOLO系列】YOLOv8算法(尖端SOTA模型)
|
C++
c++ unordered_map4种遍历方式
c++ unordered_map4种遍历方式
1138 0
|
监控 Java Android开发
微信Mars——xlog使用全解析
微信Mars——xlog使用全解析 如约而至,微信在12月19日开源了底层的通信库——Mars,其中有一个部分,是一个高性能的日志模块——xlog。
6406 0
|
SQL 前端开发
一篇文章讲明白IPage使用大概
一篇文章讲明白IPage使用大概
451 0
|
数据可视化 数据处理 Python
如何使用Python实现一个基于均线的交易策略
【10月更文挑战第9天】本文介绍了如何使用Python实现一个基于均线的交易策略。主要步骤包括导入所需库(如`pandas`、`numpy`和`matplotlib`),加载股票或期货的历史数据,计算均线和其他指标,实现交易策略逻辑,以及可视化交易结果。示例代码展示了如何根据均线交叉点进行开仓、止损和止盈操作,并提供了注意事项,如数据来源、交易成本和风险管理。
1099 7