Run this tutorial: Open in Colab | Launch Binder
Quickstart: your first bootstrap
tsbootstrap resamples time series. The whole public API is one function, bootstrap, configured with a typed method specification. To get going we run a block bootstrap, read its results, and ask diagnose which method fits the data.
[1]:
# On Colab or Binder, install tsbootstrap first (skipped if already present):
try:
import tsbootstrap # noqa: F401
except ImportError:
%pip install -q "tsbootstrap[examples]"
A small series
We use a stationary AR(1) process so the dependence structure is known.
[2]:
import numpy as np
rng = np.random.default_rng(0)
n, phi = 200, 0.6
x = np.zeros(n)
for t in range(1, n):
x[t] = phi * x[t - 1] + rng.standard_normal()
x[:5]
[2]:
array([ 0. , 0.12573022, -0.05666673, 0.60642261, 0.46875368])
One bootstrap call
MovingBlock(block_length="auto") picks the block length with the Politis-White rule. The result carries the samples plus provenance and out-of-bag primitives.
[3]:
from tsbootstrap import MovingBlock, bootstrap
result = bootstrap(x, method=MovingBlock(block_length="auto"), n_bootstraps=200, random_state=0)
samples = result.values()
samples.shape # (n_bootstraps, n)
[3]:
(200, 200)
Going faster (optional)
For larger runs, bootstrap accepts backend="compiled", an opt-in numba-accelerated fast path. It is equal in distribution to the default numpy path but not bit-identical, so individual replicates differ even with the same random_state. It needs the extra dependency, installed with pip install "tsbootstrap[accel]".
result_fast = bootstrap(x, method=MovingBlock(block_length="auto"), n_bootstraps=200, random_state=0, backend="compiled")
Out-of-bag mask
Observation-resampling methods record which points were left out of each replicate. This out-of-bag structure is what the EnbPI uncertainty layer builds on.
[4]:
mask = result.get_oob_mask()
mask.shape, round(float(mask.mean()), 3) # ~0.37 of points are OOB per replicate
[4]:
((200, 200), 0.361)
Which method should I use?
diagnose inspects the series (serial dependence, stationarity) and recommends method specifications. It is a heuristic starting point, not a guarantee; the decision-guide tutorial shows when each method is the right choice.
[5]:
from tsbootstrap import diagnose
diagnose(x).recommended_methods
[5]:
('StationaryBlock', 'MovingBlock', 'SieveAR')
Visualizing replicates
Each replicate is a new series that preserves the local dependence of the original.
[6]:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 3))
for i in range(5):
ax.plot(samples[i], color="tab:blue", alpha=0.35, lw=0.8)
ax.plot(x, color="black", lw=1.6, label="original")
ax.set_title("Original series and 5 moving-block replicates")
ax.set_xlabel("time")
ax.legend()
plt.show()
A confidence interval in one call
Beyond resampled series, conf_int gives a confidence interval for a statistic of the series in one call: it runs the bootstrap and reads back the interval. The call below returns a bias-corrected and accelerated (BCa) interval for the mean.
[7]:
from tsbootstrap import IID, conf_int
lower, upper, point = conf_int(x, "mean", method=IID(), kind="bca", alpha=0.1)
print(f"90% BCa interval for the mean: [{float(lower):.3f}, {float(upper):.3f}]")
90% BCa interval for the mean: [-0.099, 0.182]