# How TimesFM Handles NaN Values in Time Series: The Complete Preprocessing Pipeline

> TimesFM preprocesses time series by handling NaN values through infinite conversion, stripping NaNs, linear interpolation, and normalization. Learn its complete pipeline for dense, finite data.

- Repository: [Google Research/timesfm](https://github.com/google-research/timesfm)
- Tags: how-to-guide
- Published: 2026-04-02

---

**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`](https://github.com/google-research/timesfm/blob/main/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`](https://github.com/google-research/timesfm/blob/main/v1/src/timesfm/utils/xreg_lib.py)**: Consumes the pre-processed series for covariate handling, relying on the guaranteed finite inputs from `forecast`.
- **[`timesfm-forecasting/scripts/forecast_csv.py`](https://github.com/google-research/timesfm/blob/main/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:

```python
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:

```python
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 `forecast` method converts all infinite values to NaN immediately using `np.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`](https://github.com/google-research/timesfm/blob/main/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`](https://github.com/google-research/timesfm/blob/main/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.