# Wrong values calculating FFT with EEG Bands using Numpy

First of all I have to say I am very new to these matters. I am trying to apply FFT algorithm to some values obtained by EEG bands. I found the following code but I am unable to make it work correctly. import numpy as np

fs = 200
#data = np.random.uniform(0, 100, 1024)  # 2 sec of data b/w 0.0-100.0

data = np.array([(-0.27,-0.09,0.16,0.01,0.67,0.65,-1.59,0.11,-0.36,0.69,0.94,0.43,-0.53,-0.57,0.98,-0.97),(-0.74,-0.56,0.76,0.58,1.79,2.22,-4.96,-0.25,-1.19,1.57,2.95,1.47,-1.00,-1.06,2.97,-3.43),
(-0.89,-1.50,1.76,1.72,2.09,4.04,-7.97,-1.30,-2.09,1.11,4.82,2.57,-0.01,0.05,4.64,-6.44),
(-0.84,-2.78,3.00,2.88,2.00,6.36,-11.46,-2.36,-3.22,-0.01,6.96,3.84,1.85,2.11,6.64,-10.31),
(-0.39,-4.27,4.26,4.57,1.09,8.77,-14.78,-4.09,-4.40,-1.87,9.03,5.12,4.86,5.31,8.76,-14.77)])

print("After data")
# Get real amplitudes of FFT (only in postive frequencies)
fft_vals = np.absolute(np.fft.rfft(data))
print("After fft_vales")
print(fft_vals)
# Get frequencies for amplitudes in Hz
fft_freq = np.fft.rfftfreq(len(data), 1.0/fs)
print("After fft_freq")
print(fft_freq)
# Define EEG bands
eeg_bands = {'Delta': (0, 4),
'Theta': (4, 8),
'Alpha': (8, 12),
'Beta': (12, 30),
'Gamma': (30, 45)}

# Take the mean of the fft amplitude for each EEG band
eeg_band_fft = dict()
for band in eeg_bands:
freq_ix = np.where((fft_freq >= eeg_bands[band][0]) &
(fft_freq <= eeg_bands[band][1]))[0]
eeg_band_fft[band] = np.mean(fft_vals[freq_ix])

print(eeg_band_fft)


I am getting the following errors when it goes into the for.

/home/xxxx/.local/lib/python3.8/site-packages/numpy/core/fromnumeric.py:3372: RuntimeWarning: Mean of empty slice.
return _methods._mean(a, axis=axis, dtype=dtype,
/home/xxxx/.local/lib/python3.8/site-packages/numpy/core/_methods.py:170: RuntimeWarning: invalid value encountered in double_scalars
ret = ret.dtype.type(ret / rcount)


What am I missing or what's wrong?

As I said above, I am very new to this matter so please, try to explain everything as simple as possible.

This is the result I get:

band        val
0  Delta  64.642945
1  Theta        NaN
2  Alpha        NaN
3   Beta        NaN
4  Gamma  25.851368


This is how the file I am reading looks like. It is a file from a 16 electrodes reading with nearly 200k entries. I have only taken the first entries of the file in order to test this code snippet.

There are a few things going on:

1.) Your data is actually only length 5 (made up of 5 longer components). This means when you call fft_freq = np.fft.rfftfreq(len(data), 1.0/fs) your array containing the frequencies of the FFT is only length 3! I think the main issue I'm having is that I'm not sure what your data actually represents: multiple electrodes?

2.) I think you're using np.where wrong. Basically it's not returning a slice which appears to be what you're trying to get.

3.) Even if a single array in your data represents an FFT of a single channel, the length is not nearly long enough to get anything useful. If we take the frequencies of data[0] we get [ 0. 12.5 25. 37.5 50. 62.5 75. 87.5 100. ]. Not even one bin per band so you need to increase the length of your data. This is probably why freq_ix returns an empty array sometimes.

I was basically doing the same thing here in lines 45-68. A little different but more or less the same idea.

Also highly recommend using the MNE package. :)

• I have a huge file with nearly 200k entries. It's a reading from 16 electrodes so it is composed of 16 columns. The data I am using is just the first rows of this file, each array inside np.array is one row from this file. I am very new to this so I am totally lost. Can you help me get a working solution? Because probably I am messing things up here. I will add anything necessary to my post in order to assist. – NeoChiri Sep 24 '20 at 7:20
• I have added a screenshot of the file so you can see how it is. – NeoChiri Sep 24 '20 at 7:58
• I would just start by working on a single electrode. Then when that works, you can scale easily. If you don't know how Fourier Transforms work, read on that first. I assume each electrode data you have is many, many samples long? Feel free to contact me directly. – Jacob Sundstrom Sep 24 '20 at 15:42
• Sorry to clarify: each column is an electrode? If so, then you want to get that into a np.array in a single row, then operate on that. – Jacob Sundstrom Sep 24 '20 at 15:53
• I think I have made that mistake at first. Each column in the array is one reading of the 16 electrodes, but as far as I have been reading I guess each column in the array must be an electrode. Correct? – NeoChiri Sep 24 '20 at 17:34