2013-03-13 5 views
21

में पावरिंग पावर स्पेक्ट्रम मेरे पास 301 मानों के साथ एक सरणी है, जिसे 301 फ्रेम के साथ मूवी क्लिप से एकत्र किया गया था। इसका मतलब 1 फ्रेम से 1 मान है। फिल्म क्लिप 30 एफपीएस पर चल रहा है, इसलिए वास्तव में 10 सेकंड लंबापाइथन

अब मैं इस "सिग्नल" (दाएं एक्सिस के साथ) का पावर स्पेक्ट्रम प्राप्त करना चाहता हूं। मैंने कोशिश की:

X = fft(S_[:,2]); 
pl.plot(abs(X)) 
pl.show() 

मैं भी करने की कोशिश की:

X = fft(S_[:,2]); 
pl.plot(abs(X)**2) 
pl.show() 

हालांकि मुझे नहीं लगता कि यह असली स्पेक्ट्रम है।

संकेत: enter image description here

स्पेक्ट्रम: enter image description here

शक्ति स्पेक्ट्रम:

enter image description here

किसी को भी इस के साथ कुछ मदद दे सकते हैं? मैं Hz में एक साजिश रखना चाहता हूं।

+2

क्यों आप * "यह वास्तविक स्पेक्ट्रम नहीं है" *? –

उत्तर

37

Numpy एक सुविधा समारोह, np.fft.fftfreq आवृत्तियों FFT घटकों के साथ जुड़े गणना करने के लिए है:

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

data = np.random.rand(301) - 0.5 
ps = np.abs(np.fft.fft(data))**2 

time_step = 1/30 
freqs = np.fft.fftfreq(data.size, time_step) 
idx = np.argsort(freqs) 

plt.plot(freqs[idx], ps[idx]) 

enter image description here

ध्यान दें कि सबसे बड़ा आवृत्ति आप अपने मामले में देखते हैं 30 हर्ट्ज नहीं है, लेकिन

In [7]: max(freqs) 
Out[7]: 14.950166112956811 

आप कभी भी बिजली स्पेक्ट्रम में नमूना आवृत्ति नहीं देखते हैं। यदि आपके पास नमूने की संख्या भी थी, तो आप अपने मामले में Nyquist frequency, 15 हर्ट्ज तक पहुंच गए होंगे (हालांकि numpy ने इसे -15 के रूप में गणना की होगी)।

+0

उपर्युक्त आपकी टिप्पणी में, क्या आवृत्तियों में आपके द्वारा उपयोग की जाने वाली kHz इकाइयों की बजाय Hz इकाइयां होनी चाहिए? –

+1

दरअसल, @ सैम, समीक्षा के लिए धन्यवाद, ने जवाब संपादित किया है। – Jaime

+0

इस मामले में एक्स- और वाई-अक्ष लेबल क्या हैं? – FaCoffee

3

numpy fft पेज http://docs.scipy.org/doc/numpy/reference/routines.fft.html से:

जब इनपुट एक एक समय डोमेन संकेत और एक = fft (क), np.abs (ए) इसके आयाम स्पेक्ट्रम और np.abs है (ए) ** 2 इसकी शक्ति स्पेक्ट्रम है। चरण स्पेक्ट्रम np.angle (ए) द्वारा प्राप्त किया जाता है।

+0

मैंने साजिश को np.abs (ए) ** 2 के साथ जोड़ा। हालांकि, मैं इसे कैसे साजिश कर सकता हूं ताकि मैं एचजे को देख सकूं? मुझे संदेह है कि यह 0 से 301 हर्ट्ज तक है, जब मेरे पास बिल्कुल 301 नमूने हैं: पी – Ojtwist

+1

आपको खुद को करना है: एफएफटी केवल समान दूरी वाले डेटा (जैसे नियमित ग्रिड पर) के बारे में जानता है, भौतिक मात्रा नहीं। –

+0

http://stackoverflow.com/questions/13397393/unit-of-fftdft-x-axis –

13

यदि दर नमूना दर (एचजे) है, तो np.linspace(0, rate/2, n) एफएफटी में प्रत्येक बिंदु की आवृत्ति सरणी है। आप rfft का उपयोग अपने डेटा में fft गणना करने के लिए कर सकते हैं वास्तविक मूल्यों है:

import numpy as np 
import pylab as pl 
rate = 30.0 
t = np.arange(0, 10, 1/rate) 
x = np.sin(2*np.pi*4*t) + np.sin(2*np.pi*7*t) + np.random.randn(len(t))*0.2 
p = 20*np.log10(np.abs(np.fft.rfft(x))) 
f = np.linspace(0, rate/2, len(p)) 
plot(f, p) 

enter image description here

संकेत एक्स 4Hz & 7HZ पाप लहर में शामिल है, इसलिए वहाँ 4Hz & 7HZ में दो चोटियों कर रहे हैं।

+1

'fft.rfft' का उपयोग करते समय एक छोटा सुधार:' पी [0] - = 6.02; पी [-1] - = 6.02' ('absfft2 [0]/= 2; absfft2 [-1]/= 2') - उदाहरण देखें संख्यात्मक व्यंजनों पी। 653 – denis

+2

मुझे लगता है कि कोड चलाने के लिए अंतिम पंक्ति 'pl.plot (f, p) 'होना चाहिए। और आपके उत्तर के लिए धन्यवाद यह बहुत व्यावहारिक है। – wancharle

2

चूंकि एफएफटी इसके केंद्र पर सममित है, आधे मान पर्याप्त हैं।

import numpy as np 
import matplotlib.pyplot as plt 

fs = 30.0 
t = np.arange(0,10,1/fs) 
x = np.cos(2*np.pi*10*t) 

xF = np.fft.fft(x) 
N = len(xF) 
xF = xF[0:N/2] 
fr = np.linspace(0,fs/2,N/2) 

plt.ion() 
plt.plot(fr,abs(xF)**2)