我看到有人在演示中使用了这个,但我很难复制他所做的。下面是他演示中的一张幻灯片:
![Sinewave decomposition via FFT](https://istack.dev59.com/EVAzm.webp)
很酷。他使用FFT分解数据集,然后绘制了FFT指定的适当正弦波。
因此,为了重新创建他所做的内容,我创建了一系列对应于2个正弦波组合的点:
我首先导入
![Sinewave decomposition via FFT](https://istack.dev59.com/EVAzm.webp)
很酷。他使用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()
现在我想将这个波(或者说点所暗示的波)分解回原始的两个正弦波:
# 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
并获取sin3
的fft
: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()
好的,不确定该怎么做。
我想要得到类似sin1和sin2的数据集:
plt.plot(sin1)
plt.show()
plt.plot(sin2)
plt.show()
我理解了 fft3
数据集中复数的实部和虚部,但不确定如何从中派生出 sin1
和 sin2
数据集。
我知道这与编程关系较小,与数学关系较大,但是否有人能给个提示?
编辑:Mark Snyder 的答案更新:
使用 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
处出现了奇怪的线条,有人知道这是什么或是什么导致的吗?
编辑:
上面的问题已经在评论中被Mark回答了,谢谢!
sin1
或sin2
(或告诉我它们的频率,以便我可以推导出它们),对吧?这是我尝试的图形,看起来很酷,但并没有告诉我太多信息。除非我当然不知道如何解释它:plt.scatter(fft3.real, fft3.imag, color='red')
- MetaStack