I am using the FFT function in NumPy to do some signal processing. I have array called signal
which has one data point for each hour and has a total of 576 data points. I use the following code on signal
to look at its fourier transform.
t = len(signal)
ft = fft(signal,n=t)
mgft=abs(ft)
plot(mgft[0:t/2+1])
I see two peaks but I am unsure as to what the units of the x axis are i.e., how they map onto hours? Any help would be appreciated.
The FFT calculates sum of its input sampled at discrete time points multiplied by dimensionless values; the units of the result of the FFT are those of its input; there is no scaling by time or frequency in the process.
The FFT sums samples xk in the original units (U) multiplied by unitless complex values (due to discretization) e−2πj⋅. Thus the units after FFT remain the same as for the original signal, i.e. U.
We can obtain the magnitude of frequency from a set of complex numbers obtained after performing FFT i.e Fast Fourier Transform in Python. The frequency can be obtained by calculating the magnitude of the complex number. So simple ab(x) on each of those complex numbers should return the frequency.
The "Fast Fourier Transformation" (FFT) is an important measurement method in the science of audio and acoustics measurement. It converts a signal into individual spectral components and thereby provides frequency information about the signal.
Given sampling rate FSample
and transform blocksize N
, you can calculate the frequency resolution deltaF
, sampling interval deltaT
, and total capture time capT
using the relationships:
deltaT = 1/FSample = capT/N
deltaF = 1/capT = FSample/N
Keep in mind also that the FFT returns value from 0
to FSample
, or equivalently -FSample/2
to FSample/2
. In your plot, you're already dropping the -FSample/2
to 0
part. NumPy includes a helper function to calculate all this for you: fftfreq.
For your values of deltaT = 1 hour
and N = 576
, you get deltaF = 0.001736 cycles/hour = 0.04167 cycles/day
, from -0.5 cycles/hour
to 0.5 cycles/hour
. So if you have a magnitude peak at, say, bin 48 (and bin 528), that corresponds to a frequency component at 48*deltaF = 0.0833 cycles/hour = 2 cycles/day.
In general, you should apply a window function to your time domain data before calculating the FFT, to reduce spectral leakage. The Hann window is almost never a bad choice. You can also use the rfft
function to skip the -FSample/2, 0
part of the output. So then, your code would be:
ft = np.fft.rfft(signal*np.hanning(len(signal)))
mgft = abs(ft)
xVals = np.fft.fftfreq(len(signal), d=1.0) # in hours, or d=1.0/24 in days
plot(xVals[:len(mgft)], mgft)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With