How TimesFM Handles NaN Values in Time Series: The Complete Preprocessing Pipeline
TimesFM automatically cleans input time series through a four-step pipeline: converting infinite values to NaN, stripping leading NaNs, linearly interpolating interior gaps, and optionally normalizing—ensuring the transformer encoder always receives dense, finite data.
Time series data is rarely perfect. When using Google's TimesFM (Time Series Foundation Model) for forecasting, missing values, corrupted entries, or infinite measurements could break the transformer architecture. According to the google-research/timesfm source code, the library implements a robust preprocessing pipeline in v1/src/timesfm/timesfm_base.py that guarantees every input tensor is finite and dense before reaching the model.
The Four-Step NaN Handling Pipeline in TimesFM
The forecast method in TimesFmBase orchestrates a deterministic cleaning sequence that handles any combination of leading gaps, interior holes, and infinite values.
Step 1: Converting Non-Finite Values to NaN
Before any model computation begins, the forecast method (lines 84-90) converts every input series into a NumPy array and standardizes all invalid entries. Using np.isfinite, the code detects both np.nan and np.inf (positive or negative infinity), replacing any non-finite value with np.nan. This standardization ensures downstream functions only deal with one type of missing value marker.
Step 2: Stripping Leading NaN Values
The helper function strip_leading_nans (lines 77-92) removes contiguous NaN values from the very start of the series. The model cannot process a context window that begins with missing data, so this step shifts the series forward until it finds the first finite value. If the entire series consists of NaNs, the function handles this edge case by returning an appropriate empty or zero-filled structure that triggers the fallback logic in the next step.
Step 3: Linear Interpolation for Interior Gaps
For remaining gaps inside the series, linear_interpolation (lines 94-128) fills holes by connecting the nearest valid data points with straight-line interpolation. The routine scans for NaN segments, calculates the slope between the bounding valid points, and inserts intermediate values. If interpolation fails—such as when a series contains no valid points to serve as anchors—the function falls back to filling the entire series with the global mean of the dataset or zero, preventing runtime errors.
Step 4: Optional Normalization
After imputation completes, the pipeline may apply _normalize if the normalize=True flag is passed to forecast. This step scales the now-clean series independently of the NaN handling logic and does not affect the missing value imputation process.
Implementation Details in timesfm_base.py
The core preprocessing logic resides in specific functions within the base implementation:
| Function | Lines | Purpose |
|---|---|---|
forecast |
84-90 | Entry point; converts non-finite values to NaN |
strip_leading_nans |
77-92 | Removes leading contiguous NaN blocks |
linear_interpolation |
94-128 | Fills interior gaps via linear interpolation |
Additional files interact with this cleaned data:
v1/src/timesfm/utils/xreg_lib.py: Consumes the pre-processed series for covariate handling, relying on the guaranteed finite inputs fromforecast.timesfm-forecasting/scripts/forecast_csv.py: Demonstrates CLI usage that automatically benefits from the built-in NaN handling when loading CSV data.
Practical Examples: Forecasting with Missing Data
Basic Usage with Automatic Cleaning
The forecast method handles all preprocessing transparently. Pass raw data containing NaNs and infinities directly:
import numpy as np
from timesfm import TimesFmBase, TimesFmHparams, TimesFmCheckpoint
# Initialize model (use TimesFmTorch or TimesFmJax in production)
ckpt = TimesFmCheckpoint(version="torch", path="path/to/checkpoint")
hparams = TimesFmHparams()
model = TimesFmBase(hparams, ckpt)
# Series with leading NaNs, infinities, and interior gaps
raw_series = [
[np.nan, np.nan, 1.2, np.inf, 2.5, np.nan, 4.0, 5.1],
[0.0, 1.0, np.nan, 3.0, 4.0, np.nan, np.nan, 7.0],
]
# Automatic cleaning happens inside forecast()
mean_forecast, full_forecast = model.forecast(raw_series, freq=[0, 0])
print("Mean forecast shape:", mean_forecast.shape)
Under the hood, the model executes np.where(np.isfinite(...), ..., np.nan), strips the first two NaNs from the first series, and interpolates the gaps at positions 4 and 6.
Manual Preprocessing for Inspection
If you need to inspect or modify the cleaned data before inference, call the helper functions directly:
from timesfm.timesfm_base import strip_leading_nans, linear_interpolation
import numpy as np
def clean_series(series):
arr = np.array(series, dtype=float)
arr = np.where(np.isfinite(arr), arr, np.nan) # Step 1
arr = strip_leading_nans(arr) # Step 2
arr = linear_interpolation(arr) # Step 3
return arr
cleaned = [clean_series(s) for s in raw_series]
# Now cleaned contains dense, finite arrays ready for the model
Summary
- Standardization first: The
forecastmethod converts all infinite values to NaN immediately usingnp.isfinite(lines 84-90). - Leading gap removal:
strip_leading_nans(lines 77-92) ensures the context window never starts with missing data. - Interior imputation:
linear_interpolation(lines 94-128) fills holes linearly, falling back to mean or zero if interpolation is impossible. - Architecture safety: These steps guarantee the TimesFM transformer encoder receives only dense, finite-valued tensors, preventing runtime crashes on dirty real-world data.
Frequently Asked Questions
Does TimesFM handle infinite values or just NaN?
TimesFM treats both infinities and NaNs as missing data. In timesfm_base.py lines 84-90, the code uses np.isfinite to detect np.inf, -np.inf, and np.nan, converting all non-finite entries to np.nan before the cleaning pipeline proceeds.
What happens if my entire time series consists of NaN values?
If linear_interpolation cannot find valid bounding points to interpolate between, it falls back to filling the series with the global mean of the input batch or zero. This ensures the function returns a finite array rather than crashing the inference pipeline.
Can I disable automatic NaN handling and preprocess manually?
Yes. The helper functions strip_leading_nans and linear_interpolation are exposed in timesfm_base.py and can be invoked independently. You can clean your data manually, then pass the dense arrays to forecast, which will skip redundant conversion if the inputs are already finite.
Is normalization required for the NaN handling to work correctly?
No. Normalization via _normalize is an independent, optional step that occurs after the NaN imputation sequence completes. Enabling or disabling the normalize parameter does not affect the detection, stripping, or interpolation logic.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →