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.