Quickstart

Installation

Requires Python 3.10 or higher.

# with uv (recommended):
uv add tsbootstrap                   # core: i.i.d. and block methods
uv add "tsbootstrap[models]"         # adds AR / ARIMA / VAR / sieve (statsmodels)

# with pip:
pip install tsbootstrap
pip install "tsbootstrap[models]"

Model-based methods (ResidualBootstrap, SieveAR) require the models extra. They import statsmodels lazily and raise a clear install hint if the extra is missing.

Basic usage

All methods share one entry point: tsbootstrap.bootstrap(). Pass the data and a method specification; receive a BootstrapResult.

import numpy as np
from tsbootstrap import bootstrap, MovingBlock

x = np.random.default_rng(0).standard_normal(200)

result = bootstrap(
    x,
    method=MovingBlock(block_length="auto"),
    n_bootstraps=999,
    random_state=0,
)

samples = result.values()      # ndarray shape (999, 200)
oob     = result.get_oob_mask()  # ndarray shape (999, 200)

result is a BootstrapResult: a sequence of BootstrapSample objects plus a BootstrapRunMetadata provenance record.

Choosing a method

Block methods resample contiguous blocks and preserve short-range dependence. Residual methods regenerate the series recursively from a fitted model.

from tsbootstrap import (
    bootstrap,
    IID, MovingBlock, CircularBlock, StationaryBlock,
    NonOverlappingBlock, TaperedBlock,
    ResidualBootstrap, SieveAR,
    AR, ARIMA, VAR,
)

# Baseline, no serial dependence assumed
bootstrap(x, method=IID())

# Block methods (block_length defaults to "auto" = Politis-White selection)
bootstrap(x, method=MovingBlock())
bootstrap(x, method=CircularBlock())
bootstrap(x, method=StationaryBlock())           # avg_block_length parameter
bootstrap(x, method=NonOverlappingBlock())
bootstrap(x, method=TaperedBlock(window="bartlett"))

# Model-based (requires the models extra: uv add "tsbootstrap[models]")
bootstrap(x, method=ResidualBootstrap(model=AR(order=2)))
bootstrap(x, method=ResidualBootstrap(model=ARIMA(order=(1, 1, 1))))
bootstrap(x, method=SieveAR())

Unsure which method fits? Use diagnose():

from tsbootstrap import diagnose

d = diagnose(x)
print(d.recommended_methods)
print(d.notes)

Inputs

X can be a NumPy array (1-D or 2-D), a Python list, or a pandas / Polars DataFrame or Series. The function coerces everything to a (n, d) float64 array internally.

import pandas as pd

s = pd.Series(x)
result = bootstrap(s, method=MovingBlock(), n_bootstraps=100)

Reproducibility

Pass random_state (an integer seed, a NumPy Generator, or a SeedSequence) for reproducible results. Each replicate runs on its own index-bound generator, so results are identical regardless of whether jobs run serially or in parallel.

r1 = bootstrap(x, method=MovingBlock(), n_bootstraps=100, random_state=42)
r2 = bootstrap(x, method=MovingBlock(), n_bootstraps=100, random_state=42)
import numpy as np
assert np.array_equal(r1.values(), r2.values())

sktime ecosystem

If you use the sktime forecasting framework, the same methods are available as skbase.BaseObject estimator classes under tsbootstrap.adapters.

from tsbootstrap.adapters import MovingBlockBootstrap

est = MovingBlockBootstrap(block_length=10, n_bootstraps=100, random_state=0)
for sample in est.bootstrap(x):
    ...  # each sample is an ndarray of shape (n,)

See sktime / skbase adapters for the full adapter reference.