Time Series Analysis with Python: Forecasting Made Simple

Published: (January 27, 2026 at 06:00 PM EST)
4 min read
Source: Dev.to

Source: Dev.to

Time Series Analysis with Python: Forecasting Made Simple

Image credit: Antranias via Pixabay

Every business runs on predictions. How many units will we sell next quarter? What will demand look like during the holiday season? When should we increase inventory?

These questions require time‑series forecasting—analyzing historical patterns to predict future values.

The good news: Python makes time‑series analysis accessible. You don’t need a PhD in statistics—just the right approach and the right tools.


Why Time Series Is Different

  • Order matters – Yesterday’s value influences today’s.
  • Temporal dependence – Last year’s pattern might repeat this year.
  • This violates assumptions of many standard statistical techniques, so you can’t just throw a time series into a regular regression and expect good results.

Understanding the unique properties of time series is essential before diving into techniques.


Core Components of a Time Series

ComponentDescription
TrendLong‑term direction (increasing, decreasing, or stable). Example: sales may trend upward as a company grows.
SeasonalityRegular, predictable patterns that repeat at fixed intervals (e.g., retail sales spike in December, ice‑cream sales peak in summer).
Cyclical patternsLonger‑term fluctuations that aren’t as regular as seasonality (e.g., economic cycles).
Residual (noise)What’s left after removing trend and seasonality; may still contain meaningful variation.

Decomposition helps you understand what’s driving your data before you try to forecast it.


Essential Python Packages

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.stattools import adfuller
from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_absolute_error, mean_squared_error
  • pandas – Handles time‑indexed data naturally.
  • statsmodels – Provides classical time‑series methods.
  • scikit‑learn – Offers evaluation metrics.

For more advanced work, consider Prophet (Meta), pmdarima (auto‑ARIMA), and sktime (unified time‑series interface).


Preparing Your Data

# Load data with datetime parsing
df = pd.read_csv('sales_data.csv', parse_dates=['date'])
df.set_index('date', inplace=True)

# Ensure regular frequency (daily in this example)
df = df.asfreq('D')

# Handle missing values
df = df.interpolate(method='time')

Why frequency matters: Many time‑series methods assume regular intervals. Gaps or irregular timestamps cause problems.


Visual Exploration

# Plot the raw series
plt.figure(figsize=(12, 6))
plt.plot(df['sales'])
plt.title('Daily Sales Over Time')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.show()

# Decompose to see components
decomposition = seasonal_decompose(df['sales'],
                                  model='additive',
                                  period=365)
decomposition.plot()
plt.show()

Look for obvious patterns: trend, seasonal spikes, outliers, structural breaks. This visual inspection guides your modeling choices.


Checking Stationarity

A stationary series has constant mean, variance, and autocorrelation structure. Most real‑world series aren’t stationary.

result = adfuller(df['sales'])
print(f'ADF Statistic: {result[0]}')
print(f'p-value: {result[1]}')

If the p‑value is above a typical threshold (e.g., 0.05), the series is likely non‑stationary and may need differencing or transformation.


Splitting Data for Forecasting

# Simple time‑based split
split_date = '2023-01-01'          # example split point
train = df[:split_date]
test  = df[split_date:]

# Or split by proportion
train_size = int(len(df) * 0.8)
train = df[:train_size]
test  = df[train_size:]

The test set must come after the training set; otherwise, evaluation is meaningless.


Forecast Evaluation Metrics

# Assume `predictions` is a pandas Series aligned with `test`
mae  = mean_absolute_error(test['sales'], predictions)
rmse = np.sqrt(mean_squared_error(test['sales'], predictions))
mape = np.mean(np.abs((test['sales'] - predictions) / test['sales'])) * 100

print(f'MAE: {mae:.2f}')
print(f'RMSE: {rmse:.2f}')
print(f'MAPE: {mape:.2f}%')
  • MAPE is intuitive but undefined when actuals are zero.
  • MAE and RMSE are more robust but less directly interpretable.

Time‑Series Cross‑Validation

from sklearn.model_selection import TimeSeriesSplit

tscv = TimeSeriesSplit(n_splits=5)

for train_idx, test_idx in tscv.split(df):
    train_fold = df.iloc[train_idx]
    test_fold  = df.iloc[test_idx]
    # Fit model on `train_fold` and evaluate on `test_fold`

Each fold trains on historical data and tests on a subsequent period, providing a realistic estimate of forecast accuracy.


Common Pitfalls

  • Ignoring stationarity – Fitting models to non‑stationary data yields unreliable forecasts.
  • Overfitting – Complex models may fit training data perfectly but generalize poorly.
  • Ignoring seasonality – Leads to systematic errors.
  • Look‑ahead bias – Accidentally using future information during training.
  • Over‑reliance on point forecasts – Always consider prediction intervals.

Baselines & Simplicity

  • Naïve forecast – Tomorrow equals today.
  • Seasonal naïve – Next January equals last January.

If your sophisticated model can’t beat these baselines, it isn’t adding value.

Exponential smoothing methods are often simpler than ARIMA and perform comparably.

Rule of thumb: Start simple; add complexity only when it demonstrably improves forecasts.


End of cleaned markdown.

Time Series Forecasting FAQ

Questions

  • phet?
  • How do I handle missing values?
  • Can I use machine learning for time series?
  • What if my series has multiple seasonal patterns?
  • How do I forecast multiple related time series?
  • What about external factors that affect my series?
  • How do I communicate uncertainty to stakeholders?
  • What resources should I use to learn more?

Key Points

  • Time series forecasting doesn’t require advanced mathematics. It requires understanding the patterns in your data and choosing appropriate methods.
  • Start with visualization and decomposition. Check stationarity.
  • Try simple methods first. Compare against baselines. Always include uncertainty in your forecasts.
  • With Python’s powerful libraries, reliable forecasts are within reach for any data analyst willing to learn the fundamentals.

This article was refined with the help of AI tools to improve clarity and readability.

Back to Blog

Related posts

Read more »

Python 3.13 and 3.14 are now available

Builds and Functions now support Python 3.13 and Python 3.14 alongside the previously supported Python 3.12. Projects without a specified Python version continu...

Problem 12: Find Pairs with Target Sum

Problem Description Write a function that finds all unique pairs of numbers in a list that add up to a given target sum. The function should return a list of t...