科学数据可视化-如何使用Python的numpy和SciPy库进行一维傅里叶变换
geant小白
2024年04月14日 15:25

Numpy和SciPy库的官方网址+python使用手册网址:

https://numpy.org/doc/stable/user/numpy-for-matlab-users.html

https://numpy.org/doc/stable/user/numpy-for-matlab-users.html

https://docs.scipy.org/doc/scipy/tutorial/index.html#user-guide

https://docs.scipy.org/doc/scipy/tutorial/index.html#user-guide

https://docs.python.org/3/library/index.html

https://docs.python.org/3/library/index.html

https://docs.python.org/3/library/stdtypes.html#comparisons

https://docs.python.org/3/library/stdtypes.html#comparisons

 

NumPy和SciPy都可以进行傅里叶变换,这个教程来比较一下两个库的用法。SciPy我是参考下面的教程

https://blog.csdn.net/qq_27825451/article/details/88553441

https://blog.csdn.net/qq_27825451/article/details/88553441

 

注意这里有一个“显示负号”的设置,又学到了一个使用python画图包matplotlib的技巧。

源代码

import numpy as np

from scipy.fftpack import fft, ifft

import matplotlib.pyplot as plt

from matplotlib.pylab import mpl

 

#mpl.rcParams['font.sans-serif']=['SimHei']

mpl.rcParams['axes.unicode_minus']=False

 

x=np.linspace(0,1,1400)

y=7*np.sin(2*np.pi*200*x)+5*np.sin(2*np.pi*400*x)+3*np.sin(2*np.pi*600*x)

fft_y=fft(y)

N=1400

x=np.arange(N)

half_x=x[range(int(N/2))]

abs_y=np.abs(fft_y)

angle_y=np.angle(fft_y)

normalization_y=abs_y/N

normalization_half_y=normalization_y[range(int(N/2))]

 

plt.figure

plt.subplot(231)

plt.plot(x,y)

plt.title('Original Signal')

 

plt.subplot(232)

plt.plot(x,fft_y,'black')

plt.title('Bilateral amplitude (not absolutely)', fontsize=9, color='black')

 

plt.subplot(233)

plt.plot(x,abs_y,'r')

plt.title('Bilateral amplitude (without normalization)', fontsize=9, color='red')

 

plt.subplot(234)

plt.plot(x,angle_y,'violet')

plt.title('Bilateral phase', fontsize=9, color='violet')

 

plt.subplot(235)

plt.plot(x,normalization_y,'g')

plt.title('Bilateral amplitude (normalization)', fontsize=9, color='green')

 

plt.subplot(236)

plt.plot(half_x,normalization_half_y,'blue')

plt.title('Single amplitude (normalization)', fontsize=9, color='blue')

 

plt.show()

另一种是通过NumPy进行傅里叶变换

 

python如何进行一维傅里叶变换和逆变换

在Python中,可以使用numpy库中的fft模块来进行一维傅里叶变换(DFT)和逆傅里叶变换(IDFT)。

 

以下是一个示例代码:

 

import numpy as np

import matplotlib.pyplot as plt

 

# 创建一个信号

t = np.linspace(0, 1, 50)  # 时间序列

x = np.cos(2*np.pi*5*t) + np.sin(2*np.pi*12*t)  # 信号,包含5Hz和12Hz的成分

 

# 一维傅里叶变换

X = np.fft.fft(x)

freqs = np.fft.fftfreq(len(x))  # 计算频率轴

 

# 绘制频谱

plt.figure()

plt.stem(freqs, np.abs(X), 'b', markerfmt=" ", basefmt="-b")

plt.title('FFT of Signal')

plt.xlabel('Frequency [Hz]')

plt.ylabel('Magnitude')

 

# 一维逆傅里叶变换

x_inverse = np.fft.ifft(X)

 

# 绘制原始信号和逆变换后的信号

plt.figure()

plt.subplot(2, 1, 1)

plt.plot(t, x, 'b')

plt.title('Original Signal')

plt.subplot(2, 1, 2)

plt.plot(t, x_inverse.real, 'r')

plt.title('Inverse FFT of Signal')

 

plt.show()

这段代码首先创建了一个包含两种频率成分的信号,然后使用numpy.fft.fft进行了傅里叶变换,并绘制了频谱图。接着使用numpy.fft.ifft进行了逆傅里叶变换,并比较了原始信号和逆变换后的信号。

 

源代码如下:

import numpy as np

import matplotlib.pyplot as plt

 

t=np.linspace(0, 0.1, 50)

x=np.cos(2*np.pi*5*t)+np.sin(2*np.pi*12*t)

fft_x=np.fft.fft(x)

freqs=np.fft.fftfreq(len(x))

 

plt.figure()

plt.stem(freqs, np.abs(fft_x), 'b', markerfmt=" ", basefmt="-b")

plt.title('FFT of Signal')

plt.xlabel('Frequency [Hz]')

plt.ylabel('Magnitude')

 

x_inverse=np.fft.ifft(fft_x)

plt.figure()

plt.subplot(2, 1, 1)

plt.plot(t, x, 'b')

plt.title('Original Signal')

plt.subplot(2, 1, 2)

plt.plot(t, x_inverse, 'r')

plt.title('Inverse FFT of Signal')

plt.show()

我这里取出的点较少,只有50个点。这是的图像明显是不对的,右边未能覆盖一个完整的周期。Linspace的用法也不对。我将点扩大到500个时

这时的图像就没有问题了。

源代码修改为

import numpy as np

import matplotlib.pyplot as plt

 

t=np.linspace(0, 1, 500)

x=np.cos(2*np.pi*5*t)+np.sin(2*np.pi*12*t)

fft_x=np.fft.fft(x)

freqs=np.fft.fftfreq(len(x))

 

plt.figure()

plt.stem(freqs, np.abs(fft_x), 'b', markerfmt=" ", basefmt="-b")

plt.title('FFT of Signal')

plt.xlabel('Frequency [Hz]')

plt.ylabel('Magnitude')

 

x_inverse=np.fft.ifft(fft_x)

plt.figure()

plt.subplot(2, 1, 1)

plt.plot(t, x, 'b')

plt.title('Original Signal')

plt.subplot(2, 1, 2)

plt.plot(t, x_inverse, 'r')

plt.title('Inverse FFT of Signal')

plt.show()