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 and block_density=1.0.
# 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.1

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.1
File Size Uploaded
tsgap-0.6.1.tar.gz 511.0 kB Details

Built distribution (wheel)

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

Total release size: 535.5 kB

Release files / tsgap-0.6.1.tar.gz

Download URL tsgap-0.6.1.tar.gz
Size 511.0 kB
Tags Source
SHA-256 checksum
How to use checksums
fe78f3c5eea2b3215e785f86c3b637b4e0990b5fdbb20fb3f318621638af0432
BLAKE2b-256 checksum
How to use checksums
fce80121e05a2d8d950b3f24e5efb3e879200cd4d5c7de1836fb365a96f3de9d
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.1-py3-none-any.whl

Download URL tsgap-0.6.1-py3-none-any.whl
Size 24.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad80593ea7d60e770e13405335f7c6e7629ecaebbc153b7e704e10e9fe8dce2e
BLAKE2b-256 checksum
How to use checksums
5ec5cff8296a0bc56c8dc67802191aef245f7ba89fb070623b879e6597385428
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

This release

0.6.1 This release

2 release files

0.6.0

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