rem*_*rem 3 python numpy fft phase
下面是比较 fft 相位图与 2 种不同方法的代码:
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack
phase = np.pi / 4
f = 1
fs = f*20
dur=10
t = np.linspace(0, dur, num=fs*dur, endpoint=False)
y = np.cos(2 * np.pi * t + phase)
Y = scipy.fftpack.fftshift(scipy.fftpack.fft(y))
f = scipy.fftpack.fftshift(scipy.fftpack.fftfreq(len(t)))
p = np.angle(Y)
p[np.abs(Y) < 1] = 0
fig, ax = plt.subplots(2, 1)
ax[0].plot(t, y)
ax[1].plot(f*fs, p, label='from fft')
ax[1].phase_spectrum(y, fs, window=None, label='from phase_spectrum')
plt.legend()
plt.show()
Run Code Online (Sandbox Code Playgroud)
这是结果:
这是当信号周期数不是整数时的结果:
我有几个问题:
在回答之前,先做一个小注释:
删除该p[np.abs(Y) < 1] = 0行。大多数频谱的幅度都低于 1,这就是为什么这条线的频谱看起来大多像一条位于 0 处的平坦线。
现在回答:
phase_spectrum做了三件事与你不同:
np.unwrap(np.angle(Y)).angle_spectrum改用。sides='twosided'给phase_spectrum调用。现在,关于获取频率下的相位f:
为此,您必须使用不展开的阶段。
您是对的,如果没有整数个周期,则无法直接提取单音信号的相位。这是因为信号的频率并不正好落在 FFT 中任何频率仓的顶部。不过,您可以通过最近的 bin 的相位获得近似值。您还可以对频谱进行正弦插值,以获得所需频率的值。
如果您只关心单个频率的相位f,那么您根本不应该使用 FFT。FFT 计算所有频率的相位和幅度。如果您只关心单个频率,只需执行Y_at_f = y @ np.exp(2j * np.pi * f * t)并通过 获得该相位即可np.angle(Y_at_f)。
| 归档时间: |
|
| 查看次数: |
4906 次 |
| 最近记录: |