
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:
- Start with complete data, or record which values were originally observed.
- Generate a missingness scenario with a fixed seed.
- Run an imputation method on
X_missing. - 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.
Learn More
Maintain Python code quality in Quarto Markdown files using lintquarto
lintquarto is a package for running linters, formatters, static type checkers and code analysis tools on Python code in Quarto markdown (.qmd) files.
Read moreCyNetDiff: A Python Library for Accelerated Implementation of Network Diffusion Models
CyNetDiff is a Python package for accelerating network diffusion simulations, recently accepted into the pyOpenSci ecosystem.
Read moreNavigating LLMs in Open Source: pyOpenSci's New Peer Review Policy
Generative AI products are reducing the effort and skill necessary to generate large amounts of code. In some cases, this strains volunteer peer review programs like ours. Learn about pyOpenSci’s …
Read more