scipy通过快速傅里叶变换实现滤波

本文介绍了scipy库中fft模块的应用,包括Fourier变换的基本原理、离散Fourier变换(DFT)的fft函数示例,以及如何利用频域信息进行数据滤波,展示了从时域到频域转换的过程和实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

fft模块简介

scipy官网宣称,fftpack模块将不再更新,或许不久之后将被废弃,也就是说fft将是唯一的傅里叶变换模块。

Fourier变换极其逆变换在数学上的定义如下

F ( ω ) = ∫ − ∞ ∞ f ( t ) e − i ω t d t f ( t ) = π 2 ∫ − ∞ ∞ F ( ω ) e i ω t d ω F(\omega)=\int^\infty_{-\infty}f(t)e^{-i\omega t}\text dt\\ f(t)=\frac{\pi}{2}\int^\infty_{-\infty}F(\omega)e^{i\omega t}\text d\omega F(ω)=f(t)etdtf(t)=2πF(ω)etdω

下表整理出一部分与Fourier变换相关的函数,其中FFT为快速Fourier变换(Fast Fourier Transform);DCT为离散余弦变换(Discrete Cosine Transform);DST为离散正弦变换(discrete sine transform),另外,函数的前缀和后缀有如下含义

  • i表示逆变换;
  • 2, n分别表示2维和n维
正变换逆变换
通用fft, fft2, fftnifft, ifft2, ifftn
实数域rfft, rfft2, rfftnirfft, irfft2, irfftn
厄米对称hfft, hfft2, hfftnihfft, ihfft2, ihfftn
离散余弦变换dct, dctnidct, idctn
离散正弦变换dst, dstnidst, idstn
汉克尔变换fhtifht
移动零频fftshiftifftshift
DFT采样频率fftfreqifftfreq

fft函数示例

在数值计算中,一切输入输出均为离散值,所以实际上用到的是离散Fourier变换,即DFT,其功能是将离散的采样变换为一个离散的频谱分布。

下面将手动创建一组采样点,并添加一点噪声,然后通过FFT获取其频域信息。

import numpy as np
from scipy import fft

PI = np.pi*2
fs = 60     #采样频率
T = 100     #采样周期数
N = fs*T    #采样点
t = np.linspace(0, T, N)
noise = 2 * np.random.randn(*t.shape)
s = 2 * np.sin(PI * t) + 3 * np.sin(22 * PI * t) + noise
F = fft.fft(s)
f = fft.fftfreq(N, 1.0/fs)

其中,t为时间序列,s为模拟的采样点,F是Fourier变换之后的结果。但由于fft默认是在复数域上的,故而可以查看其实部、虚部、模和辐角的值。

下面对采样点以及Fourier变换的结果进行绘制

import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(2,2,1)
ax.plot(t, s)
ax.set_title("t vs s")
f_abs = np.abs(F)
ax = fig.add_subplot(2,2,2)
ax.plot(f, f_abs)
ax.set_title("fs vs |F|")

xlims = [[0,2], [21,23]]
for i, xlim in enumerate(xlims):
    ax = fig.add_subplot(2,2,3+i)
    ax.stem(f, f_abs)
    ax.set_title("fs vs |F|")
    ax.set_xlim(xlim)

plt.show()

结果为

在这里插入图片描述

f = 1 f=1 f=1 f = 22 f=22 f=22处被筛选了出来。

滤波

有了这个,就可以在频域上对数据进行滤波,其思路是,对f_abs中的值进行阈值分割,例如,只筛选出低频部分,然后看一下滤波效果

fig = plt.figure(1)
f_filt = F * (np.abs(f) < 2)
s_filt = fft.ifft(f_filt)
ax = fig.add_subplot()
ax.plot(t, s, lw=0.2)
ax.plot(t, s_filt.real, lw=2)
ax.set_title("threshold=2")
ax.set_xlim([0,10])
plt.show()

效果如下

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微小冷

请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值