I have data which when plotted looks like the green line in the below image. The data is from the walking-motion of a reinforcement-learning-model in a simulation and therefore the values do not really correspond to time. But the dataset is 10000 steps long. I used the steps as the time variable. This is just a part of the plot.
To me the signal looks like a periodic signal with a lot of noise. Therefore my idea was to use Fourier Transform to identify a few underlying main frequencies and then simplify the signal. Thus cancelling out the noise.
I create the FFT like this:
s = ppo2_df['obs_4'].values
fft = np.fft.fft(s)
T = 1 # sampling interval
N = s.size
# 1/T = frequency
f = np.linspace(0, 1 / T, N)
plt.figure(figsize=(20, 5))
plt.ylabel("Amplitude")
plt.xlabel("Frequency [1/Step]")
# plot only half the spectrum
barlist = plt.bar(f[:N // 2], np.abs(fft)[:N // 2], align='edge', width=0.001)
max_inds = np.argsort(np.abs(fft)[:N // 2])[-5:]
for i in max_inds:
barlist[i].set_color('r')
plt.show()
Next I try to reconstruct the signal from the FFT using IFFT using the 5 strongest frequencies discovered. My issue is that the eventual plot does not fluctuate around 0 like the original plot but around 0.4 instead. I don't know the mistake I must have made:
# filter n max amplitude frequencies
max_freq = f[max_inds]
max_fft = np.zeros(N)
max_fft[max_inds] = fft[max_inds]
x = np.fft.ifft(max_fft)
fig = px.line(y=np.abs(x[:1000]))
fig.show()
Can you tell me what I did wrong? (e.g. I am unsure if i chose a sensible sampling interval T = 1
)
EDIT:
The data can be copied from here:
fig = px.line(y=x.real[:1000])
. The output signal seemed a lot less accurate because of this $\endgroup$ – Philipp May 27 '20 at 21:04