gpt4 book ai didi

python - 在python中将FFT绘制为一组正弦波?

转载 作者:行者123 更新时间:2023-12-04 01:35:33 24 4
gpt4 key购买 nike

我看到有人在演示中这样做,但我很难重现他的能力。这是他演讲的幻灯片:

Sinewave decomposition via FFT

很酷。他使用 FFT 分解了一个数据集,然后绘制了 FFT 指定的适当正弦波。

因此,为了重现他所做的事情,我创建了一系列对应于 2 个正弦波组合的点:

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

x = np.arange(0, 10, 0.01)
x2 = np.arange(0, 20, 0.02)
sin1 = np.sin(x)
sin2 = np.sin(x2)
x2 /= 2
sin3 = sin1 + sin2
plt.plot(x, sin3)
plt.show()

Composed wave

现在我想将这个波(或者更确切地说,这些点所暗示的波)分解回原来的 2 个正弦波:
# goal: sin3 -> sin1, sin2
# sin3
array([ 0.00000000e+00, 2.99985000e-02, ... 3.68998236e-01])
# sin1
array([ 0. , 0.00999983, 0.01999867, ... -0.53560333])
# sin2
array([ 0. , 0.01999867, 0.03998933, ... 0.90460157])

我首先导入 numpy并获得 fftsin3 :
import numpy as np
fft3 = np.fft.fft(sin3)

好的,就我所知。现在我有一个包含复数的数组:
array([ 2.13316069e+02+0.00000000e+00j,  3.36520138e+02+4.05677438e+01j,...])

如果我天真地绘制它,我会看到:
plt.plot(fft3)
plt.show()

fft naively plotted

好吧,不知道该怎么办。

我想从这里获得看起来像 sin1 和 sin2 的数据集:
plt.plot(sin1)
plt.show()

sin1 data plotted
plt.plot(sin2)
plt.show()

sin2 data plotted

我理解 fft3 中复数的实部和虚部数据集,我只是不确定如何处理它们来导出 sin1sin2来自它的数据集。

我知道这与编程的关系不大,而与数学的关系更大,但是有人可以在这里给我一个提示吗?

编辑:更新马克·斯奈德的回答:

使用 Mark 的代码,我能够得到我所期望的结果,并最终使用了这种方法:
def decompose_fft(data: list, threshold: float = 0.0):
fft3 = np.fft.fft(data)
x = np.arange(0, 10, 10 / len(data))
freqs = np.fft.fftfreq(len(x), .01)
recomb = np.zeros((len(x),))
for i in range(len(fft3)):
if abs(fft3[i]) / len(x) > threshold:
sinewave = (
1
/ len(x)
* (
fft3[i].real
* np.cos(freqs[i] * 2 * np.pi * x)
- fft3[i].imag
* np.sin(freqs[i] * 2 * np.pi * x)))
recomb += sinewave
plt.plot(x, sinewave)
plt.show()

plt.plot(x, recomb, x, data)
plt.show()

稍后我会让它返回重组的波浪列表,但现在我遇到了一个我不太明白的异常。首先我这样称呼它,简单地传入一个数据集。
decompose_fft(sin3, threshold=0.0)

但看起来不错,但我在 y=0.2 收到这条奇怪的线路有谁知道这可能是什么或导致它的原因是什么?

Looks really good

编辑:

马克在评论中已经回答了上述问题,谢谢!

最佳答案

离散傅立叶变换存在一些问题,在使用连续对应变换时不会立即明显。一方面,您输入的周期性应该与您的数据范围相匹配,因此如果您使用:

x = np.linspace(0, 4*np.pi, 200)

然后你可以按照你最初的想法:
sin1 = np.sin(x)
sin2 = np.sin(2*x)
sin3 = sin1 + sin2
fft3 = np.fft.fft(sin3)

由于在 FFT sin直接进入虚部,您可以尝试仅绘制虚部:
plt.plot(fft3.imag)
plt.show()

您应该看到以 x=2 为中心的峰值和 x=4对应于原始正弦分量,其频率为“每个信号 2 个”(从 0 到 4 pi 的 sin(x))和“每个信号 4 个”(从 0 到 4 pi 的 sin(2x))。

要绘制所有单个组件,您可以使用:
for i in range(1,100):
plt.plot(x, fft3.imag[i] * np.sin(i*x)/100)
plt.show()

关于python - 在python中将FFT绘制为一组正弦波?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59725933/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com