# Calculating values of frequency bins in Python

I have to use FFT to determine the period of waves inside a signal. After applying FFT on a window of 10000 point from a signal, I get something like this:

What I don't understand is that FFT is supposed to return frequencies, but if the input is a longer signal with the same frequencies, the values of frequencies returned by FFT will change.

So for an array of N length, the result of the FFT will always be N/2 (after removing the symmetric part), how do I interpret these return values to get the period of the major frequency?

I use the fft function provided by scipy in python.

Edit:

Some answers pointed out the sampling frequency. I don't understand what the number of samples per second has to do with the size of the periodic pattern, the FFT returns frequencies right? And then for a specified frequency f, I can do t=1/f and then t will be something like 300 points for example. That means we have a repeating pattern every 300 point, I'm not sure about this. To summaries I have a periodic signal and I need to identify the period T0

• You need to use fftfreq to get the frequencies: docs.scipy.org/doc/scipy-dev/reference/generated/… – endolith May 5 '17 at 14:11
• The way you define the $f_0$ in Magnitude vs Frequency plot, it looks like a difference between two peaks, not the value of frequency. Looking for periodicity in spectrum is done via cepstrum analysis. But if I now understand you correctly, based on the spectrum, you want to know if there is a periodicity in signal every N samples. Why not to use the autocorrelation instead? – jojek May 5 '17 at 14:26
• The FFT does NOT return frequencies. It returns magnitudes (and phases) of correlation to a limited basis set of sinusoidal frequencies. Those basis frequencies depend on the sample rate and FFT length. – hotpaw2 May 5 '17 at 15:33

This is simply how Discrete Fourier Transform (i.e. Fourier Transform theory applied on sampled signal) works. You get an output of length N if your input has length N, and after removal of symmetric part, what you get are $\frac{N}{2}$ points that span frequencies 0 (DC component) to Nyquist frequency ($\frac{F_s}{2}$).

For this same reason, the more points your signal have (let's say for a fixed sampling rate $F_s$) the more resolved your FFT output is since the spacing between each frequency bin in the output is: $$\frac{F_s/2}{N/2} = \frac{F_s}{N}$$

UPDATE:

Regardless of the sampling frequency the FFT returns $N$ data points for an input with $N$ samples. What we say is that all the points of the output spread the circle: $[0;2\pi]$ in radian/sample or sometimes denoted $[0;1]$ in cycles/sample (called the normalized frequency). All these bins correspond to how many cycles, or oscillations you might have between each samples. You can measure at best half a cycle between each sample (for real signals). This is usually converted back into frequency simply by knowing the sampling rate.

So indeed if your signal is longer, you will have a longer output. Now what I was pointing out is that if your signal is longer but recorded with same $F_s$, i.e. it actually last longer in time, then you will resolve smaller frequency (since you have more time in total, this gives finer information in the frequency domain). That is, the bins are closer to each other in frequency domain ($\Delta f = F_s/N = 1/T$ get smaller). So basically, the longer you record, for whatever sampling rate, the finer resolution you get in the frequency domain.

In summary, if you do not know $F_s$ the bins are located (after removal of symmetrical part):

• span $[0,0.5]$, and spaced by $1/N$, and the unit is cycle/sample, OR
• span $[0,\pi]$, spaced by $2\pi/N$, unit is radian/sample

Then if you know $F_s$, simply transform back into Hertz, knowing that it must span $[0, F_s/2]$.

• the question wasn't clear, i updated my question – Hamza Tahiri May 5 '17 at 11:59

Like you said, after removal of the symmetric part the result will have approx $N/2$ points. You must calculate the frequencies corresponding to the n'th bin $f_n$: $$f_n = \dfrac{n\cdot F_s}{N}$$

Since you are using Python, you can do it by using the fftfreq function (it returns negative frequencies instead of ones above the Nyquist). However, here is an example how to do it manually:

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

T = 10  # Duration in seconds
f0 = 100  # Fundamental frequency
Fs = 1000  # Sampling frequency

# Time domain signal
t = np.arange(0, T*Fs)/Fs
x = np.sin(2*np.pi*f0*t)
N = x.size

# DFT
X = np.fft.fft(x)
X_db = 20*np.log10(2*np.abs(X)/N)
#f = np.fft.fftfreq(N, 1/Fs)
f = np.arange(0, N)*Fs/N

plt.plot(f, X_db)
plt.grid()
plt.show()


• how to get the sampling frequency? all i have is an array of N points, and all i need is the size(in number of points) of the repeating pattern, or periodic signal – Hamza Tahiri May 5 '17 at 11:15
• You should know the sampling frequency upfront i.e from the device specification. Otherwise if you have the time vector then sampling frequency can be calculated from the time spacing. For example Fs = 1/(t[1]-t[0]) . – jojek May 5 '17 at 11:19
• the time vector is [0,1,2,3...] and thus Fs=1, when using this Fs i get a FTT between -0.5 and 0.5 – Hamza Tahiri May 5 '17 at 11:30
• If this is the time vector then indeed the Sampling frequency is 1 Hz. However does it make sense that your signal was sampled every second? I.e., does the data collected for the second signal (30000 points) correspond to 8 hours and 20 minutes in total? – jojek May 5 '17 at 11:34
• that's what am saying i only need the size of the periodic window in points, not in seconds, and for this i don't see any need to know how many samples were recorded per second – Hamza Tahiri May 5 '17 at 11:36

If you are using unitless samples (no sample rate given), then

T = N/k


Where T is the period length in samples, N is the FFT length in samples, and k is the FFT result bin index of interest, for instance a result bin where there is a local (or nearby) magnitude (amplitude) peak. Note that k should be such that k <= N/2, or else you are looking at duplicate complex conjugate results given strictly real input.

• this is what i was looking for, but still your answer give me the smallest repeating pattern, since it was repeated thousands of times, how about bigger patterns that repeated only few times? – Hamza Tahiri May 9 '17 at 9:17