Python 振幅和相位谱。移相使振幅保持不变

Python 振幅和相位谱。移相使振幅保持不变,python,signal-processing,fft,ifft,phase,Python,Signal Processing,Fft,Ifft,Phase,我有在相关点具有等效间隔和相应测量值的数据。作为一个例子,以下是我收集的数据摘录: y=[2.118,2.1289,, 2.1374, 2.1458, 2.1542, 2.1615, 2.1627, 2.165 2.1687…] 各点之间的间隔为0.1 所以,我需要从数据中得到振幅谱(振幅对频率)和相位谱(相位角对频率)。 此外,我应该将数据的相位偏移负90度(-pi/2) 在移相并保持振幅不变的情况下,我需要进行逆fft并获得新信号。我想用Python来做这件事 你能给我举个例子吗 我使用的代

我有在相关点具有等效间隔和相应测量值的数据。作为一个例子,以下是我收集的数据摘录:

y=[2.118,2.1289,, 2.1374, 2.1458, 2.1542, 2.1615, 2.1627, 2.165 2.1687…]

各点之间的间隔为0.1

所以,我需要从数据中得到振幅谱(振幅对频率)和相位谱(相位角对频率)。 此外,我应该将数据的相位偏移负90度(-pi/2)

在移相并保持振幅不变的情况下,我需要进行逆fft并获得新信号。我想用Python来做这件事

你能给我举个例子吗

我使用的代码取自另一个SO问题,但我做了一些修改

## Perform FFT WITH SCIPY
signalFFT = np.fft.fft(y)

## Get Power Spectral Density
signalPSD = np.abs(signalFFT) ** 2
signalPhase = np.angle(signalFFT)

## Shift the phase py +90 degrees
new_signalPhase =(180/np.pi)*np.angle(signalFFT)+90 


## Get frequencies corresponding to signal 
fftFreq = np.fft.fftfreq(len(signalPSD), 0.1)

## Get positive half of frequencies
i = fftFreq>0

##
plt.figurefigsize=(8,4)
#plt.plot(fftFreq[i], 10*np.log10(signalPSD[i]));

plt.plot(fftFreq[i], new_signalPhase[i]);
plt.ylim(-200, 200);
plt.xlabel('Frequency Hz');
plt.ylabel('Phase Angle')
plt.grid()
plt.show()
问题是,我想重新生成信号,具有相同的振幅,但相移。我知道答案是smth与ifft相关,但我应该如何准备数据?你能告诉我进一步的步骤吗


这是经过一些修改的代码。我们应用傅里叶变换,对变换后的信号进行相移,然后进行逆傅里叶变换以产生相移时域信号

请注意,变换是通过rfft()irfft()完成的,相移是通过简单地将变换后的数据乘以cmath.rect(1,phase)来完成的。相移相当于将复变换信号乘以exp(i*相位)

在左面板的图形中,我们显示原始信号和移位信号。新信号提前90度。在右面板中,我们显示了左轴上的功率谱。在这个例子中,我们有一个单一频率的功率。相位在右轴上绘制。但是再一次,因为我们只有一个频率的功率,相位谱显示其他地方的噪声

#!/usr/bin/python

import matplotlib.pyplot as plt
import numpy as np
import cmath

# Generate a model signal
t0 = 1250.0
dt = 0.152
freq = (1./dt)/128

t = np.linspace( t0, t0+1024*dt, 1024, endpoint=False )
signal = np.sin( t*(2*np.pi)*freq )

## Fourier transform of real valued signal
signalFFT = np.fft.rfft(signal)

## Get Power Spectral Density
signalPSD = np.abs(signalFFT) ** 2
signalPSD /= len(signalFFT)**2

## Get Phase
signalPhase = np.angle(signalFFT)

## Phase Shift the signal +90 degrees
newSignalFFT = signalFFT * cmath.rect( 1., np.pi/2 )

## Reverse Fourier transform
newSignal = np.fft.irfft(newSignalFFT)

## Uncomment this line to restore the original baseline
# newSignal += signalFFT[0].real/len(signal)


# And now, the graphics -------------------

## Get frequencies corresponding to signal 
fftFreq = np.fft.rfftfreq(len(signal), dt)

plt.figure( figsize=(10, 4) )

ax1 = plt.subplot( 1, 2, 1 )
ax1.plot( t, signal, label='signal')
ax1.plot( t, newSignal, label='new signal')
ax1.set_ylabel( 'Signal' )
ax1.set_xlabel( 'time' )
ax1.legend()

ax2 = plt.subplot( 1, 2, 2 )
ax2.plot( fftFreq, signalPSD )
ax2.set_ylabel( 'Power' )
ax2.set_xlabel( 'frequency' )

ax2b = ax2.twinx()
ax2b.plot( fftFreq, signalPhase, alpha=0.25, color='r' )
ax2b.set_ylabel( 'Phase', color='r' )


plt.tight_layout()

plt.show()
这是图形输出


你好,卡姆兰,欢迎来到SO!在这里提出问题时,向我们展示您已经尝试解决问题的方法,并且非常具体地说明您所遇到的困难,这一点很重要。阅读这将帮助我们帮助你。现在,如果你不了解FFT是如何工作的,或者你根本不知道如何编码,我们很难判断。。。一次只问一个问题Kamran,请看下面我的答案和代码。相移信号由三行代码生成,即傅里叶变换、乘以exp(i相位)和逆变换。@DrM非常感谢。如果我错了,请纠正我,exp(I相位)的乘法只是exp(I w t)幂的加法,我的意思是在DFT表达式中。我说得对吗?exp(I w t)x exp(I相位)等于exp[I(w t+phi)],也就是说,它移动相位。换言之,将傅里叶变换后的信号乘以exp(i相位),得到的是被相同相位偏移的信号的FT。这适用于任何输入信号。