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()
../_images/tutorials_quickstart_12_0.png

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]