1. 由相似性理解傅立叶变换
傅立叶变换可一理解成是某一个函数和正弦函数的相似性,其是一个函数和正弦函数的乘积。
2. 傅立叶变换的使用场景
有一个曲线 f(t), 若认为高频部分是噪声,即可先将其转换到频域,滤波(滤掉高频成分),再进行逆傅立叶变换(如下图所示)。
3. 傅立叶变换的过程
伪代码:
再来对比一下
4. 实现三角波,并进行傅立叶变换
import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import fft,ifft
#三角波
def triangle_wave(x, c, h):
"""
x: 横坐标
c: 周期
h: 最大振幅
"""
res_x = x % c
if res_x == 0:
y = 0
elif res_x <= c / 2: # 上升段
y = ((2 * h) / c ) * res_x
else: # 下降段
y = ((-2 * h) / c ) * res_x + 2 * h
return y
x=np.linspace(0,10,200)
#这是一种画三角波的方法
# y1=np.array([triangle_wave(t, 2, 3) for t in x])
# plt.plot(x,y1)
# plt.show()
# # fromfunc 将计算单个值的函数转换为一个能对数组中每个元素进行计算的func函数
# fromfunc(func,nin,nout) nin是func输入的参数,nout是func返回值的个数
# triangle_ufunc1=np.frompyfunc(triangle_wave,3,1)
# y2=triangle_ufunc1(x, 2, 3)
# y2=y2.astype(np.float) #将其类型从object转换为float
# pl.plot(x,y2)
# plt.show()
# # vectorize功能同fromfunc
triangle_ufunc2=np.vectorize(triangle_wave,otypes=[np.float])
y3=triangle_ufunc2(x, 2, 3)
plt.plot(x,y3)
plt.show()
# 进行傅立叶变换
fft_y3 = fft(y3)
print(fft_y3)
Q :怎样绘制傅立叶变换之后的图像,以及怎样滤波,以及绘制滤波之后切逆傅立叶变换的时域的图像?
# 傅立叶变换
# 三角波
#三角波
def triangle_wave(x, c, h):
"""
x: 横坐标
c: 周期
h: 最大振幅
"""
res_x = x % c
if res_x == 0:
y = 0
elif res_x <= c / 2: # 上升段
y = ((2 * h) / c ) * res_x
else: # 下降段
y = ((-2 * h) / c ) * res_x + 2 * h
return y
x=np.linspace(0,10,200)
y=np.array([triangle_wave(t, 2, 3) for t in x])
N = len(y)
f = np.fft.fft(y)
frequency_domain_intensity = np.abs(f/N)
# 滤波
f_real = np.real(f)
real_eps = 0.3 * f_real.max()
f_real[(f_real < real_eps) & (f_real > -real_eps)] = 0
f_imag = np.imag(f)
imag_eps = 0.3 * f_imag.max()
f_imag[(f_imag < imag_eps) & (f_imag > -imag_eps)] = 0
f1 = f_real + f_imag * 1j
# 逆傅立叶变换
y1 = np.fft.ifft(f1)
y1 = np.real(y1)
plt.figure(figsize=(8, 8))
plt.subplot(311)
plt.plot(x, y, 'g-', lw=2)
plt.title('triangle_wave', fontsize=15)
plt.subplot(312)
w = np.arange(N) * 2*np.pi / N
plt.stem(w, frequency_domain_intensity, linefmt='r-', markerfmt='ro')
plt.title('frequency domain', fontsize=15)
plt.subplot(313)
plt.plot(x, y1, 'b-', lw=2, markersize=4)
plt.title('filtered signal', fontsize=15)
plt.grid(True)
plt.tight_layout(1.5, rect=[0, 0.04, 1, 0.96])
plt.suptitle("fft", fontsize=17)
plt.show()
参考:
https://www.bilibili.com/video/BV1za411F76U/spm_id_from=333.788.recommend_more_video.-1
代码:
https://github.com/crystal30/ML2/blob/main/ML_base/data_analysis.ipynb