1 year ago
#382107
EnigmAI
How to detect time-periods present in a signal using FFT?
I'm trying to determine the periodicities present in a given waveform.
This is my signal, which is a sinusoidal waveform:
t_week = np.linspace(1,480, 480)
t_weekend=np.linspace(1,192,192)
T=96 #Time Period
x_weekday = 10*np.sin(2*np.pi*t_week/T)+10
x_weekend = 2*np.sin(2*np.pi*t_weekend/T)+10
x_daily_weekly_sinu = np.concatenate((x_weekday, x_weekend))
#Creating the Signal
x_daily_weekly_long_sinu = np.concatenate((x_daily_weekly_sinu,x_daily_weekly_sinu,x_daily_weekly_sinu,x_daily_weekly_sinu,x_daily_weekly_sinu,x_daily_weekly_sinu,x_daily_weekly_sinu,x_daily_weekly_sinu,x_daily_weekly_sinu,x_daily_weekly_sinu))
#Visualization
plt.plot(x_daily_weekly_long_sinu)
plt.show()
In order to determine the two periods present, which are 96 & 672, I'm creating the FFT of the waveform as follows:
f, Pxx = signal.periodogram(x_daily_weekly_long_sinu, fs = 96, window='hanning', scaling='spectrum')
#Visualization
plt.figure(figsize = (10, 8))
plt.plot(f, Pxx)
plt.xlim(0, 10)
plt.yscale('log')
plt.xlabel('Frequency (cycles/day)')
plt.ylabel('Spectrum Amplitude')
The following is the plot of frequencies that I get.
Can anyone tell why is it showing so many frequencies instead of just two distinct frequencies of 96 & 672?
I then try to extract the top frequencies from the FFT:
for amp_arg in np.argsort(np.abs(Pxx))[::-1][1:6]:
day = 1 / f[amp_arg]
print(day)
But my output gives the following values as the top frequencies instead of 96 & 672:
1.0144927536231885
0.9859154929577465
1.1666666666666667
0.875
1.4
Why is this happening? Can anyone please help me to determine the correct periods?
It would be great if I just get a final list of values representing the exact set of periods only.
python
numpy
scipy
signal-processing
fft
0 Answers
Your Answer