Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detrend Flux Time Series with Non-Linear Trend

Tags:

python

numpy

I am needing to detrend flux time series data (light curves), but I'm running into a problem when the time series data doesn't have a simple linear trend.

I've been using scipy.signal.detrend() for the detrending of linear cases, but that isn't sufficient here.

I've used numpy.polyfit() to attempt polynomial detrending, but I'm not sure what to do with the polynomial coefficients it returns.

Can someone advise me as to the next intelligent step to take? Or, if someone has a better method for detrending non-linear data, I'd be delighted to hear that as well.

like image 827
Palmetto_Girl86 Avatar asked Jan 02 '15 17:01

Palmetto_Girl86


People also ask

How do you detrend data from a time series?

Perhaps the simplest method to detrend a time series is by differencing. Specifically, a new series is constructed where the value at the current time step is calculated as the difference between the original observation and the observation at the previous time step.

How do you get rid of non linear trends?

To eliminate the nonlinear trend, fit a low-order polynomial to the signal and subtract it. In this case, the polynomial is of order 6. Plot the two new signals. The trends have been effectively removed.

How do you detrend linear trends?

To detrend linear data, remove the differences from the regression line. You must know the underlying structure of the trend in order to detrend it. For example, if you have a simple linear trend for the mean, calculate the least squares regression line to estimate the growth rate, r.

How do you detrend deterministic trends?

If the trend is deterministic (e.g. a linear trend) you could run a regression of the data on the deterministic trend (e.g. a constant plus time index) to estimate the trend and remove it from the data. If the trend is stochastic you should detrend the series by taking first differences on it.


1 Answers

In a nutshell, you take the coefficients that polyfit returns and pass them to polyval to evaluate the polynomial at the observed "x" locations.

As a stand-alone example, let's say we have something similar to the following:

import numpy as np
import matplotlib.pyplot as plt

num = 1000
x = np.linspace(0, 10, num)
y = np.exp(x)

# Add some non-stationary noise that's hard to see without de-trending
noise = 100 * np.exp(0.2 * x) * np.random.normal(0, 1, num)
y += noise

fig, ax = plt.subplots()
ax.plot(x, y, 'ro')
plt.show()

enter image description here

Note that I haven't used a polynomial function here to create y. That's deliberate. Otherwise, we'd get an exact fit and wouldn't need to "play around" with the order of the polynomial.

Now let's try detrending it with a 2nd order polynomial function (note the 2 in the line model = np.polyfit(x, y, 2)):

import numpy as np
import matplotlib.pyplot as plt

num = 1000
x = np.linspace(0, 10, num)
y = np.exp(x)

# Add some non-stationary noise that's hard to see without de-trending
noise = 100 * np.exp(0.2 * x) * np.random.normal(0, 1, num)
y += noise

# Detrend with a 2d order polynomial
model = np.polyfit(x, y, 2)
predicted = np.polyval(model, x)

fig, axes = plt.subplots(nrows=2, sharex=True)
axes[0].plot(x, y, 'ro')
axes[0].plot(x, predicted, 'k-')
axes[0].set(title='Original Data and 2nd Order Polynomial Trend')

axes[1].plot(x, y - predicted, 'ro')
axes[1].set(title='Detrended Residual')

plt.show()

enter image description here


Notice that we didn't fit the data exactly. It's an exponential function and we're using a polynomial. However, as we increase the order of the polynomial, we'll fit the function more precisely (at the risk of starting to fit noise):

enter image description here

enter image description here

enter image description here

enter image description here

like image 59
Joe Kington Avatar answered Sep 27 '22 19:09

Joe Kington