2017-03-08 1 views
1

Je vais avoir du mal à obtenir un spectre de fréquences sur une transformée de Fourier ... J'ai des données: dataspectre de puissance fft maux

que j'ai moyenne centrée, et ne semble pas avoir trop beaucoup d'une tendance ...

je tracer la transformée de Fourier de celui-ci:

fourier transform

Et je reçois quelque chose qui est pas agréable ....

Voici mon code:

def fourier_spectrum(X, sample_freq=1): 
    ps = np.abs(np.fft.fft(X))**2 
    freqs = np.fft.fftfreq(X.size, sample_freq) 
    idx = np.argsort(freqs) 

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

Comme adapté du code tiré de here.

Il semble fonctionner pour certaines données naïve vague péché:

fourier_spectrum(np.sin(2*np.pi*np.linspace(-10,10,400)), 20./400) 

sin spectrum

Mes questions sont les suivantes: J'attends un non-zéro presque partout spectre, que suis-je mal faire? Si je ne fais rien de mal, quelles sont les caractéristiques de mes données qui provoquent cela? Aussi, si je ne fais rien de mal, et que fft est juste inadapté à mes données pour une raison quelconque, que dois-je faire pour extraire des fréquences importantes de mes données?

+0

Il suffit de ne pas tracer le 0 bin du fft s'il y a trop de composants « DC ». De plus, les données semblent avoir de fortes composantes de fréquences à très basses fréquences - peuvent sembler plus "raisonnables" en regardant seulement les premières 50 cases – f5r5e5d

+0

Soustraire la moyenne du signal avant FFT-qui supprime le gros composant à "DC" "(C'est-à-dire, bin 0 de la FFT). Egalement/alternativement, tracez le 'log10 (abs (...))' (c'est-à-dire, dB, ou décibels) de la sortie FFT pour avoir une meilleure idée de ce qui se passe. –

+0

Regardez également les estimateurs spectraux statistiques comme [periodogram] (https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.periodogram.html) et les méthodes connexes dans 'scipy.signal'. –

Répondre

0

Il s'avère que je ne comprenais pas les unités de l'axe des x dans le spectre de fréquence, qui est Hz. Comme mes intervalles d'échantillonnage étaient de l'ordre d'une seconde et que ma période était de l'ordre du jour, les seules unités vraiment visibles sur mon spectre de fréquence étaient ~ 1/s (sur les bords) à environ 1/m (près de le milieu), et quelque chose avec une période plus longue que cela était indiscernable de 0. Mon malentendu provenait du graphique sur this tutoriel, où ils font des conversions de sorte que les unités de l'axe des x sont dans le temps, par opposition à temps inverse. Je réécris ma fonction plotting frequency_spectrum pour faire le approprié « zoom » sur le graphique résultant ...

def fourier_spectrum(X, sample_spacing_in_s=1, min_period_in_s=5): 
    ''' 
     X: is our data 
     sample_spacing_in_s: is the time spacing between samples 
     min_period_in_s: is the minimum period we want to show up in our 
      graph... this is handy because if our sample spacing is 
      small compared to the periods in our data, then our spikes 
      will all cluster near 0 (the infinite period) and we can't 
      see them. E.g. if you want to see periods on the order of 
      days, set min_period_in_s=5*60*60 #5 hours 
    ''' 
    ps = np.abs(np.fft.fft(X))**2 
    freqs = np.fft.fftfreq(X.size, sample_spacing_in_s) 
    idx = np.argsort(freqs) 
    plt.plot(freqs[idx], ps[idx]) 
    plt.xlim(-1./min_period_in_s,1./min_period_in_s) # the x-axis is in Hz