2015-09-26 5 views
5

Ich lese eine bestimmte Spalte einer CSV-Datei als ein numpy Array. Wenn ich versuche, das fft dieses Arrays zu machen, bekomme ich eine Anordnung von NaNs. Wie bekomme ich das fft zur Arbeit? Hier ist, was ich bisher habe:Wie bekomme ich die FFT eines numply-Arrays?

#!/usr/bin/env python 
from __future__ import division 

import numpy as np 
from numpy import fft 

import matplotlib.pyplot as plt 


fileName = '/Users/Name/Documents/file.csv' 

#read csv file 
df = np.genfromtxt(fileName, dtype = float, delimiter = ',', names = True) 

X = df['X'] #get X from file 

rate = 1000. #rate of data collection in points per second 
Hx = abs(fft.fft(X)) 
freqX = fft.fftfreq(len(Hx), 1/rate) 

plt.plot(freqX,Hx) #plot freqX vs Hx 
+1

Haben Sie überprüft, ob es 'nan's in Ihrem Vektor gibt? – cel

Antwort

11

Vermutlich gibt es einige fehlende Werte in Ihrer CSV-Datei. Standardmäßig ersetzt np.genfromtxt die fehlenden Werte durch NaN.

Wenn es irgendwelche NaN s oder Inf s in einem Array, wird die fft alle NaN s oder Inf s sein.

Zum Beispiel:

import numpy as np 

x = [0.1, 0.2, np.nan, 0.4, 0.5] 
print np.fft.fft(x) 

Und wir erhalten:

array([ nan +0.j, nan+nanj, nan+nanj, nan+nanj, nan+nanj]) 

Da jedoch eine FFT auf einer regelmäßig beabstandeten Reihe von Werten arbeitet, die nicht-endliche Werte aus einer Entfernung von Array ist ein bisschen komplexer als nur sie fallen zu lassen.

pandas hat mehrere spezialisierte Operationen, um dies zu tun, wenn Sie für die Verwendung offen sind (z. B. fillna). Mit "reinem" Numpy ist es jedoch nicht so schwer.

Zuerst gehe ich davon aus, dass Sie mit einer fortlaufenden Datenreihe arbeiten, weil Sie die FFT der Werte verwenden. In diesem Fall möchten wir die NaN Werte basierend auf den Werten um sie herum interpolieren. Die lineare Interpolation (np.interp) kann in allen Situationen nicht ideal sein, aber es ist keine schlechte Standardauswahl:

Zum Beispiel:

import numpy as np 

x = np.array([0.1, 0.2, np.nan, 0.4, 0.5]) 
xi = np.arange(len(x)) 

mask = np.isfinite(x) 
xfiltered = np.interp(xi, xi[mask], x[mask]) 

Und wir erhalten:

In [18]: xfiltered 
Out[18]: array([ 0.1, 0.2, 0.3, 0.4, 0.5]) 

Wir können berechnen dann die FFT normalerweise:

In [19]: np.fft.fft(xfiltered) 
Out[19]: 
array([ 1.50+0.j  , -0.25+0.34409548j, -0.25+0.08122992j, 
     -0.25-0.08122992j, -0.25-0.34409548j]) 

... und ein gültiges Ergebnis bekommen.

+0

Ja, ich habe eine fortlaufende Reihe von Daten. Die Datenreihen, die ich habe, wurden 1000 mal pro Sekunde über eine Zeit von 20 Sekunden gesammelt. Wie würden diese fehlenden Werte nur mit numpy umgehen? –

+1

Sie sollten eine Kombination von 'np.isfinite' und' np.interp' verwenden können, wie das zweite Beispiel zeigt. (Ich habe es vor ein paar Minuten bearbeitet, also müssen Sie möglicherweise aktualisieren, um das Update zu sehen.) Hoffe, dass hilft! –

Verwandte Themen