Skip to main content

TSGap

A Python library for simulating realistic missingness in time-series data for imputation benchmarking.

TSGap separates mechanisms (why data is missing: MCAR, MAR, MNAR) from patterns (how data is missing: pointwise, block, monotone, decay, markov). Any mechanism can be combined with any pattern, making it easy to create controlled missing-data scenarios for evaluating imputation methods.

Complete data (left) vs. five mechanism+pattern combinations at 20% missing rate.

Features

  • MCAR, MAR, and MNAR missingness mechanisms
  • Pointwise, block, monotone, temporal decay, and Markov-chain patterns
  • 2D (time, features) and 3D (samples, time, features) arrays
  • Exact or calibrated missing-rate control
  • Weighted multi-driver MAR
  • Reproducible masks with NumPy random seeds
  • Existing NaNs and target dimensions preserved across patterns

Installation

pip install tsgap

For development:

git clone https://github.com/feruzoripov/tsgap.git
cd tsgap
pip install -e ".[dev]"

Requires Python 3.9 or newer and NumPy 1.19 or newer.

Quick Start

import numpy as np
from tsgap import simulate_missingness

X = np.random.default_rng(42).standard_normal((1000, 6))

# MCAR: 15% scattered missing values
X_miss, mask = simulate_missingness(X, "mcar", 0.15, seed=42)

# MAR: missingness driven by dimension 0 and arranged in blocks
X_miss, mask = simulate_missingness(
    X, "mar", 0.25, seed=42,
    pattern="block", driver_dims=[0], block_len=10
)

# Scale block length to the sequence length for long series
# The default block pattern uses block_len=10; block_frac is recommended
# for long wearable-style series where fixed 10-sample blocks are too short.
X_miss, mask = simulate_missingness(
    X, "mcar", 0.20, seed=42,
    pattern="block", block_frac=0.01
)

# Sample each block length between 1% and 5% of the time axis
X_miss, mask = simulate_missingness(
    X, "mcar", 0.20, seed=42,
    pattern="block", block_frac=(0.01, 0.05)
)

# MNAR: extreme values missing with monotone dropout
X_miss, mask = simulate_missingness(
    X, "mnar", 0.20, seed=42,
    pattern="monotone", mnar_mode="extreme"
)

print(f"Actual missing rate: {(~mask).mean():.4f}")

The returned mask uses:

mask == True  -> observed
mask == False -> missing

Documentation

Example Use Cases

  • Random telemetry loss in sensor networks
  • Activity-dependent dropout in wearable devices
  • Participant dropout in longitudinal or clinical studies
  • Gradual signal loss from sensor degradation
  • Intermittent connectivity failures with bursty missingness

Evaluation Workflow

import numpy as np
from tsgap import simulate_missingness

X = np.random.default_rng(42).standard_normal((1000, 6))
X_miss, mask = simulate_missingness(X, "mar", 0.20, seed=42, driver_dims=[0])

X_imputed = your_imputation_method(X_miss)
missing_idx = ~mask

rmse = np.sqrt(np.mean((X[missing_idx] - X_imputed[missing_idx]) ** 2))
mae = np.mean(np.abs(X[missing_idx] - X_imputed[missing_idx]))

See docs/benchmarking.md for a complete baseline workflow.

The repository also includes a runnable benchmark example:

python examples/benchmark_imputation.py

Testing

pytest tsgap/tests/ -v

Citation

@software{tsgap,
  author = {Oripov, Feruz and Korchagina, Kseniia and Bonsu, Enock Adu and Bilgin, Ali and Aras, Shravan},
  title = {TSGap: A Python Library for Composable Time-Series Missingness Simulation},
  year = {2026},
  url = {https://github.com/feruzoripov/tsgap}
}

License

MIT

Metadata

Release files for tsgap 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tsgap 0.6.0
File Size Uploaded
tsgap-0.6.0.tar.gz 391.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tsgap 0.6.0
File Interpreter ABI Platform
tsgap-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 415.7 kB

Release files / tsgap-0.6.0.tar.gz

Download URL tsgap-0.6.0.tar.gz
Size 391.3 kB
Tags Source
SHA-256 checksum
How to use checksums
54662d25be9e980538c06af98d5da6c136c03158f0d22675c3f4172a5ae951e9
BLAKE2b-256 checksum
How to use checksums
cfe5a6d0800c82c1929788874b8fcedb76f73d1665da5edce7734da1ccb17a8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.3

Release files / tsgap-0.6.0-py3-none-any.whl

Download URL tsgap-0.6.0-py3-none-any.whl
Size 24.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
57772e91a4b5ef59625aa9bf87b670e5f725040ae3678405034d42cf513be9d1
BLAKE2b-256 checksum
How to use checksums
396dd1cde35775ad7725a93e398f2e6f9e71f13afdf4477b78ae1f392f486c7f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.3

Release history Release notifications | RSS feed

0.7.0

2 release files

0.6.1

2 release files

This release

0.6.0 This release

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page