Sampling and Estimation
Bootstrap Mean (Small)
Estimate the sampling distribution of the mean by averaging B given
resamples. Each resample is a fixed literal list (values drawn with
replacement from the original), making results deterministic without relying
on RNG agreement between naive and library. Nested loops: outer over B=3
resamples, inner computes each resample mean; a final loop averages the
resample means. Library: np.mean per resample then np.mean of those
means, on identical data.
By hand
Original: [2, 4, 6] (mean=4.0). Three given resamples (n=3 each, drawn with replacement from the original): [2,2,4] → 2.667, [4,6,6] → 5.333, [6,4,2] → 4.0. Bootstrap mean = (2.667+5.333+4.0)/3 = 4.0. The nested loop makes the mean-per-resample step explicit.
original = [2, 4, 6]
resamples = [[2, 2, 4], [4, 6, 6], [6, 4, 2]]
B = len(resamples)
means = []
for rs in resamples:
total = 0.0
for v in rs:
total = total + v
means.append(total / len(rs))
boot_mean = 0.0
for m in means:
boot_mean = boot_mean + m
boot_mean = boot_mean / B
print('RESULT:', round(boot_mean, 4))
original ← [2, 4, 6]
1original = [2, 4, 6]2resamples = [[2, 2, 4], [4, 6, 6], [6, 4, 2]]values this step[2, 4, 6]originalresamples ← [[2, 2, 4], [4, 6, 6], [6, 4, 2]]
1original = [2, 4, 6]2resamples = [[2, 2, 4], [4, 6, 6], [6, 4, 2]]3B = len(resamples)values this step[[2, 2, 4], [4, 6, 6], [6, 4, 2]]resamplesB ← 3
2resamples = [[2, 2, 4], [4, 6, 6], [6, 4, 2]]3B = len(resamples)4means = []values this step3Bmeans ← []
3B = len(resamples)4means = []5for rs in resamples:values this step[]meansrs ← [2, 2, 4], total ← 8.0, v ← 4, means ← [2.6666666666666665]
pass 1 of 34means = []5for rs in resamples:6 total = 0.07 for v in rs:8 total = total + v9 means.append(total / len(rs))10boot_mean = 0.0values this step[2, 2, 4]rs4.0 → 8.0total2 → 4v[] → [2.6666666666666665]meansAll 3 passes — pass 1 is the card above pass rstotalvmeans1 [2, 2, 4] 4.0 → 8.0 2 → 4 [] → [2.6666666666666665] 2 [2, 2, 4] → [4, 6, 6] 10.0 → 16.0 4 → 6 [2.6666666666666665] → [2.6666666666666665, 5.333333333333333] 3 [4, 6, 6] → [6, 4, 2] 10.0 → 12.0 4 → 2 [2.6666666666666665, 5.333333333333333] → [2.6666666666666665, 5.333333333333333, 4.0] for rs in resamples:
4means = []5for rs in resamples:6 total = 0.0boot_mean ← 0.0
9 means.append(total / len(rs))10boot_mean = 0.011for m in means:values this step0.0boot_meanm ← 2.6666666666666665, boot_mean ← 2.6666666666666665
pass 1 of 310boot_mean = 0.011for m in means:12 boot_mean = boot_mean + m13boot_mean = boot_mean / Bvalues this step2.6666666666666665m0.0 → 2.6666666666666665boot_meanAll 3 passes — pass 1 is the card above pass mboot_mean1 2.6666666666666665 0.0 → 2.6666666666666665 2 2.6666666666666665 → 5.333333333333333 2.6666666666666665 → 8.0 3 5.333333333333333 → 4.0 8.0 → 12.0 for m in means:
10boot_mean = 0.011for m in means:12 boot_mean = boot_mean + mboot_mean ← 4.0
12 boot_mean = boot_mean + m13boot_mean = boot_mean / B14print('RESULT:', round(boot_mean, 4))values this step12.0 → 4.0boot_meanstdout ← RESULT: 4.0
13boot_mean = boot_mean / B14print('RESULT:', round(boot_mean, 4))values this stepRESULT: 4.0stdout
With the library
np.mean is applied per resample via a list comprehension, then np.mean
averages those means. Same resamples as naive; the resample means are shown
for comparison.
import numpy as np
from dalib.display import set_display
set_display()
original = [2, 4, 6]
resamples = [[2, 2, 4], [4, 6, 6], [6, 4, 2]]
B = len(resamples)
resample_means = [float(np.mean(rs)) for rs in resamples]
boot_mean = float(np.mean(resample_means))
print('B:', B)
print('resample means:', [round(m, 4) for m in resample_means])
print('RESULT:', round(boot_mean, 4))
B: 3
resample means: [2.6667, 5.3333, 4.0]
RESULT: 4.0
Honesty
This lesson shows the computation exactly, on a tiny pinned sample. The arithmetic is correct and reproducible, but with a sample this small the result is not a valid statistical finding — it demonstrates the mechanism, not evidence. Real inference needs an adequate sample size and assumption checks (e.g. B≥1000 resamples and an adequate original n); the bootstrap estimate here should be read as "how the resampling is computed," not as a conclusion about a population.
Implementation notes
- RNG parity rule: resamples are given as fixed literals rather than
generated at runtime. Python's
randomand numpy's RNG produce different sequences even with the same integer seed, so live draws would break parity. - In practice B is typically 1000–10000. Here B=3 is enough to show the structure without exceeding the 60-event trace budget.
- Bootstrap does not require knowing the population distribution. The resample variability estimates the sampling variability directly from the data.
- Cross-reference:
seeded-sample-mean(this chapter) for the mean computation each resample iteration applies;standard-error(this chapter) for the analytic SE that bootstrap approximates empirically.