Stationarity in Time Series — Tests and Transformations
Statistics
Making Time Series Ready for Modeling
Stationarity — constant mean, variance, and autocorrelation over time — is a prerequisite for most forecasting models. ADF and KPSS tests detect non-stationarity, while differencing and transformations restore it.
-
Economic Forecasting — Transform non-stationary GDP data for reliable ARIMA modeling
-
Financial Analysis — Convert price series to stationary returns for volatility modeling
-
Climate Science — Remove trends from temperature data to analyze cyclical patterns
Stationary series are predictable because their statistical properties don't wander.
A time series is stationary if its statistical properties (mean, variance, autocorrelation) do not change over time. Stationarity is a key assumption for many time series models.
DfStationary Time Series
A time series is strictly stationary if the joint distribution of is the same as for all , all time indices, and all lags .
DfWeakly Stationary
A time series is weakly (covariance) stationary if:
-
(constant mean)
-
(constant variance)
-
(autocovariance depends only on lag h)
Why Stationarity Matters
Key Insight
Most time series models (AR, MA, ARIMA) are built on the assumption of stationarity. If the series is non-stationary, parameter estimates may be unreliable and forecasts may be misleading.
Non-stationary series often exhibit:
-
Trend: systematic increase or decrease in mean
-
Seasonality: periodic fluctuations
-
Heteroscedasticity: changing variance over time
Augmented Dickey-Fuller (ADF) Test
The ADF test checks for a unit root, which indicates non-stationarity.
ADF Test Regression
Here,
- =First difference of Y at time t
- =Coefficient on lagged level (key parameter)
- =Constant (intercept)
- =Time trend
- =Number of lagged difference terms
| Hypothesis | Meaning |
|-----------|---------|
| : | Unit root present -> non-stationary |
| : | No unit root -> stationary |
Interpreting ADF
If p-value < 0.05, reject and conclude the series is stationary. If p-value > 0.05, fail to reject — the series may be non-stationary.
KPSS Test
The KPSS test has opposite hypotheses from the ADF test.
KPSS Test
Here,
- =Random walk component
- =Stationary error
- =White noise innovation
| Hypothesis | Meaning |
|-----------|---------|
| : Series is stationary | Trend-stationary |
| : Series is non-stationary | Unit root present |
Using Both Tests
Use ADF and KPSS together. If ADF rejects (stationary) and KPSS fails to reject (stationary), the series is likely stationary. If both reject, the series is borderline.
Transformations for Stationarity
Differencing
First Differencing
Here,
- =First difference — removes linear trend
- =Value at time t
For seasonal data, use seasonal differencing:
Seasonal Differencing
Here,
- =Seasonal period (e.g., 12 for monthly data)
Log Transformation
Stabilizes variance when it increases with the level of the series.
Log Transformation
Here,
- =Original positive time series
- =Transformed series with stabilized variance
Box-Cox Transformation
A family of power transformations that includes log as a special case.
Box-Cox Transformation
Here,
- =Transformation parameter (estimated from data)
Python Implementation
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller, kpss
np.random.seed(42)
# Non-stationary series (random walk + trend)
t = np.arange(200)
Y = np.cumsum(np.random.randn(200)) + 0.02 * t
# ADF test
adf_result = adfuller(Y, autolag='AIC')
print(f"ADF Statistic: {adf_result[0]:.3f}")
print(f"p-value: {adf_result[1]:.4f}")
# KPSS test
kpss_result = kpss(Y, regression='ct', nlags='auto')
print(f"KPSS Statistic: {kpss_result[0]:.3f}")
print(f"p-value: {kpss_result[1]:.4f}")
# Apply differencing
Y_diff = np.diff(Y)
adf_diff = adfuller(Y_diff, autolag='AIC')
print(f"\nAfter differencing:")
print(f"ADF p-value: {adf_diff[1]:.4f}")
Worked Example
Example: Testing Stationarity
A monthly airline passenger series shows increasing variance and trend.
-
Log transform to stabilize variance:
-
ADF test on : p-value = 0.85 -> non-stationary
-
First difference:
-
ADF test on : p-value = 0.001 -> stationary
-
Seasonal difference (s=12):
-
ADF test on : p-value = 0.000 -> stationary
The series requires both seasonal and first differencing to achieve stationarity.
Key Takeaways
Summary: Stationarity
-
A stationary time series has constant mean, variance, and autocovariance over time
-
The ADF test checks for unit roots (: non-stationary)
-
The KPSS test has opposite hypotheses (: stationary)
-
Use both tests together for more reliable conclusions
-
Differencing removes trends; log transformation stabilizes variance
-
Most ARIMA models require a stationary input series
Related Topics
-
See ARIMA Models for models that handle non-stationary data
-
See ACF and PACF for identifying autocorrelation patterns
-
See Seasonal Decomposition for separating trend, seasonal, and residual components