A complete multivariate time series beside six examples with missing values highlighted in red: pointwise, block, monotone, decay, Markov, and Gilbert-Elliott patterns.

TSGap: Reproducible missingness simulation for time-series benchmarks

Nov 9, 2026 • Feruz Oripov

TSGap is a NumPy-native Python package for creating reproducible artificial missingness scenarios for time-series imputation benchmarks.

Evaluating a time-series imputation method requires known values that can be hidden and reconstructed. The way those values are hidden matters: isolated missing points, sensor outages, dropout near the end of a recording, and bursty packet loss create very different reconstruction problems.

TSGap is a lightweight, NumPy-native Python package for creating these artificial missingness scenarios. It was recently peer reviewed and accepted by pyOpenSci.

Why separate mechanism from pattern

TSGap describes a scenario using two ideas:

  • The mechanism describes why a value is selected for masking. TSGap supports missing completely at random (MCAR), missing at random (MAR), and missing not at random (MNAR).
  • The pattern describes how missing values are arranged over time. Available patterns include pointwise, block, monotone, decay, Markov, and Gilbert-Elliott burst loss.

Separating these concepts makes experiments easier to describe and reproduce. For example, researchers can compare isolated MCAR gaps with contiguous MCAR outages while keeping the requested missing rate fixed.

There is an important interpretation detail. Pointwise MAR and MNAR preserve a direct relationship between the mechanism score and each masked value. Non-pointwise patterns reshape a mechanism-informed missingness budget into a temporal structure. They should therefore be described as structured, mechanism-informed masks rather than automatically treated as strict MAR or MNAR data-generating processes.

Create a block-missingness scenario

Install TSGap from PyPI:

pip install tsgap

The following example masks 20% of the eligible values in a two-feature time series. Each block spans between 2% and 10% of the series length.

import numpy as np

from tsgap import simulate_missingness

rng = np.random.default_rng(42)
X = rng.normal(size=(1_000, 2))

X_missing, observed_mask = simulate_missingness(
    X,
    mechanism="mcar",
    pattern="block",
    missing_rate=0.20,
    block_frac=(0.02, 0.10),
    seed=42,
)

artificially_missing = ~observed_mask & np.isfinite(X)
achieved_rate = artificially_missing.sum() / np.isfinite(X).sum()

print(f"Artificial missingness rate: {achieved_rate:.1%}")

X_missing contains NaN at the newly hidden positions. The Boolean observed_mask is False at those positions and True where data remain observed. The same seed produces the same mask, which supports reproducible benchmarking.

The missing-rate denominator is the number of originally observed, eligible entries in the selected target dimensions. Existing NaN values are preserved but do not count toward the requested artificial missingness rate. This distinction is useful when working with real sensor recordings that already contain gaps.

From simulation to evaluation

A typical benchmark can use TSGap in four steps:

  1. Start with complete data, or record which values were originally observed.
  2. Generate a missingness scenario with a fixed seed.
  3. Run an imputation method on X_missing.
  4. Evaluate predictions only at positions that TSGap artificially masked.

TSGap supports both two-dimensional arrays shaped as time by features and three-dimensional arrays shaped as samples by time by features. Target dimensions can be selected so that auxiliary variables remain available while another variable is masked.

Deterministic patterns aim for exact rate control among eligible entries. Stochastic state models such as Markov and Gilbert-Elliott masks can vary between seeds, so studies using them should report achieved rates and aggregate results across multiple seeds.

Try TSGap

TSGap is available under the MIT license:

Bug reports, feature requests, and contributions are welcome through the TSGap issue tracker.

Last modified:

Keep reading