2017-12-16 22 views
1

私は36002個のアイテムからなるデータセットを持っています。その中に含まれる周波数とそれに対応する周波数のパワー密度を知るためにFFTとPSDを行いたいと思います。python-FFTとPSDの計算

from __future__ import division 
import numpy 
import matplotlib.pyplot as plt 

#read in the pressure p_dot and time t, they are [36002,] vector 
nSteps=36002 
p_dot=numpy.genfromtxt((r'E:\p_dot.dat'), delimiter=' ')[:,2] 
t=numpy.genfromtxt((r'E:\t.dat'), delimiter=' ')[:,0] 

T=(t[-1]-t[0])/nSteps # the interval between two data points 
N=len(p_dot)//2+1 # FFT is symmetrical, so plot one half 
Y=numpy.fft.fft(p_dot) # to compare with Yhann 
hann=numpy.hanning(len(p_dot)) 
Yhann=numpy.fft.fft(hann*p_dot) 
fa=1.0/T # scan frequency 
X=numpy.linspace(0, fa/2, N, endpoint=True) # Nyquest frequency=fa/2 
plt.close() 
plt.subplot(2,1,1) 
plt.plot(x,y) 
plt.subplot(2,1,2) 
plt.plot(X, 2.0*abs(Yhann[:N])/N) 
plt.tight_layout() 
plt.show() 

しかし、結果は、少なくとも私はそう思う、間違っ判明:

私のコードです。明らかに私のデータは定期的ですが、FFTは0 Hzでスパイクしかありません。最初の1000項目の結果を参照してください。

result 1000 そして36002 result 36002 の結果何が問題なの?どうもありがとう。

Btw、誰でもPythonでオーバラップウィンドウを使用する方法を説明できますか?そしていつそれを使うべきですか?問題の解決策を探すとき、私はいつもこれらの方法を見て、それをどのように使うのか考えていません。ありがとう!

+1

0Hzはゼロ周波数、すなわち一定の信号を意味し、電気的な世界のDC成分と考える。これが測定信号の大きな成分であることは珍しいことではなく、測定することによって異なります。 元の信号から平均値を削除し、 'scipy.signal.detrend'などの' detrend'関数を使用することもできます。 あなたのコードが正しいことをしているかどうかを知る最も簡単な方法は、結果がどうなるべきかを知っている偽の信号を与えることです。 – ahed87

+0

em、手がかりを感謝します。それは本当に役立ちます。 –

答えて

0

0Hzでのピークの理由は、入力信号の平均値がゼロでないためです。これが信号のDC成分です。 1Hz程度のところにピークがありますが、これはおおよそ信号の主な周波数と思われます。

ウィンドウの機能は、通常、データの小さなセグメントで電力を計算した後、結合または平均してスペクトル推定のノイズを減らすときに適用されます。完全な信号に適用するのは問題ありませんが、それほど一般的ではありません。このすべてのウィンドウ処理と平均化は手動で行うことができますが、実際にはscipy.signal.welch関数(または同様のもの)を使用してPSDを推定することをお勧めします。それはあなたのために、すべての本を保持し、窓をつけ、平均化するなどの処理を行います。

+0

本当にありがとう!私は問題を解決しました。 –

関連する問題