Reputation: 253
I've gathered accelerometer data with a frequency of approx 50 Hz (every 0.02 sec., as exactly as Android allows it...)
Here is the plot of the magnitudes of a 10 second window of the data, on which I want to estimate power spectral density:
After applying scipy.signal.periodogram like this
fs = 50
f, Pxx_den = signal.periodogram(x, fs)
plt.semilogy(f, Pxx_den)
plt.show()
I get the following plot, showing an outliner at 0 Hz:
Is this outliner expected? I would like to feed a Machine Learning algorithm with the 3 highest PSDs but having the outliner at 0 makes me think, that something went wrong. Or is this not the case? Applying FFT also leads to a high amplitude at 0 Hz.
Upvotes: 1
Views: 1344
Reputation: 6430
This is due to the detrending that signal.periodigram
does by default.
Detrending is removing a constant or linear term (usually) from the data, defaulting to a constant-detrend. This is effectively subtracting the mean in each section of data over which the PSD is estimated. Subtracting the mean is equivalent to removing the DC or zero-frequency component from the spectrum.
I generated fake data, just Gaussian noise, with a y-offset of 5, similar to that of your data. You can see from the plot below that detrending removes the zero-frequency component, while setting detrend=False
keeps it. Keep in mind, however, that detrending may actually be useful. You may or may not care about that, depending on what type of analysis you're interested in.
from scipy import signal
import numpy as np
import matplotlib.pyplot as plt
x = np.random.randn(1000,) * 2.0 + 5.0 # White noise data, with y-offset
fs = 50.0
f, detrended_psd = signal.periodogram(x, fs)
_, psd = signal.periodogram(x, fs, detrend=False)
fig, ax = plt.subplots()
ax.semilogy(f, detrended_psd, linewidth=3.0, label='Detrended')
ax.semilogy(f, psd, linewidth=1.0, label='Not detrended')
fig.tight_layout()
ax.set_xlabel('Frequency (Hz)')
ax.set_ylabel('PSD')
Upvotes: 4