2016-08-07 25 views
2

Ich habe Probleme mit numpy Implementierung der schnellen Fourier-Transformation. Mein Signal ist nicht periodisch und daher sicherlich kein idealer Kandidat, das Ergebnis der FFT ist jedoch weit entfernt von dem, was ich erwartet habe. Es ist das gleiche Signal, einfach um einen Faktor gestreckt. I aufgetragen, um eine Sinuskurve, annähert mein Signal neben ihn, die veranschaulichen soll, dass ich die FFT-Funktion richtig nutzen:numpys schnelle Fourier-Transformation liefert unerwartete Ergebnisse

import numpy as np 
from matplotlib import pyplot as plt 

signal = array([[ 0.], [ 0.1667557 ], [ 0.31103874], [ 0.44339886], [ 0.50747922], 
    [ 0.47848347], [ 0.64544846], [ 0.67861755], [ 0.69268326], [ 0.71581176], 
    [ 0.726552 ], [ 0.75032795], [ 0.77133769], [ 0.77379966], [ 0.80519187], 
    [ 0.78756476], [ 0.84179849], [ 0.85406538], [ 0.82852684], [ 0.87172407], 
    [ 0.9055542 ], [ 0.90563205], [ 0.92073452], [ 0.91178145], [ 0.8795554 ], 
    [ 0.89155587], [ 0.87965686], [ 0.91819571], [ 0.95774404], [ 0.95432073], 
    [ 0.96326252], [ 0.99480947], [ 0.94754962], [ 0.9818627 ], [ 0.9804966 ], 
    [ 1.], [ 0.99919711], [ 0.97202208], [ 0.99065786], [ 0.90567128], 
    [ 0.94300558], [ 0.89839004], [ 0.87312245], [ 0.86288378], [ 0.87301008], 
    [ 0.78184963], [ 0.73774451], [ 0.7450479 ], [ 0.67291666], [ 0.63518575], 
    [ 0.57036157], [ 0.5709147 ], [ 0.63079811], [ 0.61821523], [ 0.49526048], 
    [ 0.4434457 ], [ 0.29746173], [ 0.13024641], [ 0.17631683], [ 0.08590552]]) 

sinus = np.sin(np.linspace(0, np.pi, 60)) 

plt.plot(signal) 
plt.plot(sinus) 

Die blaue Linie ist mein Signal, die grüne Linie ist die Sinus.

raw.pdf

transformed_signal = abs(np.fft.fft(signal)[:30]/len(signal)) 
transformed_sinus = abs(np.fft.fft(sinus)[:30]/len(sinus)) 

plt.plot(transformed_signal) 
plt.plot(transformed_sinus) 

Die blaue Linie ist transformed_signal, ist die grüne Linie die transformed_sinus.

fft.pdf

Plotten nur transformed_signal zeigt das Verhalten oben beschrieben:

enter image description here

Kann mir jemand erklären, was hier vor sich geht?

UPDATE

Ich war in der Tat ein Problem, die FFT des Aufrufs. Dies ist den richtigen Anruf und das richtige Ergebnis:

transformed_signal = abs(np.fft.fft(signal,axis=0)[:30]/len(signal)) 

enter image description here

Antwort

3

Numpys fft wird standardmäßig auf Zeilen angewendet. Da Ihre signal Variable ein Spaltenvektor ist, wird fft über die Zeilen angewendet, die aus einem Element bestehen, und gibt die Ein-Punkt-FFT jedes Elements zurück.

die Achse Option von fft geben Sie an, dass Sie FFT über den Spalten von signal angewendet werden soll, das heißt,

transformed_signal = abs(np.fft.fft(signal,axis=0)[:30]/len(signal)) 
+0

Oder, wenn die Absicht war, dass "Signal" ein 1D-Vektor ist, transformiere es mit etwas wie "np.array ([x [0] für x in Signal])" – mtrw

1

[EDIT] ich die entscheidende Sache von Stelios angegeben zu übersehen! Nichtsdestoweniger überlasse ich meine Antwort hier, da, obwohl ich die Ursache Ihres Problems nicht entdeckt habe, es immer noch wahr ist und Dinge enthält, mit denen Sie für eine brauchbare FFT rechnen müssen.

Wie Sie sagen, transformieren Sie ein nicht-periodisches Signal. Ihr Signal hat einige Wellen (höhere Harmonische), die in der FFT gut sichtbar sind. Der Sinus hat viel weniger höhere Frequenzen und besteht größtenteils aus einer DC-Komponente.

So weit so gut. Was ich nicht verstehe, ist, dass dein Signal auch eine DC-Komponente hat, die überhaupt nicht auftaucht. Könnte sein, dass dies eine Frage der Größenordnung ist.

Kern der Sache ist, dass, während die Sinus und Ihr Signal ganz gleich aussehen, sie einen ganz anderen harmonischen Inhalt haben.

Am bemerkenswertesten keine von beiden halten eine Frequenz, die der halben Sinus entspricht. Dies liegt daran, dass ein "halber Sinus" nicht durch Summierung ganzer Sinus aufgebaut wird. Mit anderen Worten: Die zugrunde liegende volle Sinuswelle ist nicht im spektralen Inhalt des Sinus über die Hälfte der Periode.

BTW mit nur 60 Samples ist etwas dürftig, Shannon gibt an, dass Ihre Sample-Frequenz mindestens doppelt so hoch wie die höchste Signalfrequenz sein sollte, da sonst Aliasing auftritt (Zuordnung von Freqs zur falschen Stelle). Mit anderen Worten: Ihr Signal sollte nach der Probennahme optisch glatt erscheinen (es sei denn, es ist diskontinuierlich oder hat eine diskontinuierliche Ableitung, wie eine Block- oder Dreieckwelle). Aber in Ihrem Fall sieht es so aus, als wären die scharfen Spitzen ein Artefakt der Unterabtastung.

+0

ich auf die FFT ganz neu bin und verstehe nicht ganz die Antwort. Ich denke, ich verstehe, dass die Signale völlig anders aussehen als die FFT und daher völlig unterschiedliche Ergebnisse liefern. Ich bin mir jedoch nicht sicher, was Sie mit der DC-Komponente meinen. Warum denkst du sollte da eins sein? Und was würden Sie vorschlagen, um dieses mögliche Größenproblem zu lindern? Ich werde versuchen, ein längeres Signal zu finden, um das Aliasing zu erklären. – Paul

+0

@Paul Jacques bezieht sich auf das [Nyquist-Shannon-Abtasttheorem] (https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem). Ihre Abtastfrequenz muss doppelt so hoch sein wie die Frequenz der höchsten Frequenzkomponente in Ihrem Signal, die Sie erfassen möchten. –

+0

Als Hinweis: Verwenden Sie mindestens 20 Vollperioden der niedrigsten Freq, die Sie erkennen möchten, und mindestens 2 Samples pro volle Periode der höchsten Freq. Und dämpfen Sie Ihr Signal allmählich am Anfang und am Ende, um Diskontinuitäten im Signal und seinen Ableitungen zu verhindern (so wird das Abschneiden bei Null nicht funktionieren, weil die Ableitungen dann einen Sprung machen) –