NumPy: 随机数
随机数
1. 你将学到
❶ Generator vs RandomState ❷ 常见分布 ❸ 随机种子 ❹ choice / permute / shuffle ❺ 蒙特卡洛入门
2. 一个开发者的真实故事
(1) 痛点
Bob 问"掷 1000 次骰子出现 3 个 6 的概率?"他翻概率论课本找二项分布公式,算了半天还怕算错。
(2) 解法
Alice 用 rng.binomial(1000, 1/6, size=100000) 1 行搞定——"不用查公式,直接模拟 10 万次。"
(3) 收益
Bob 发现蒙特卡洛方法把复杂的概率问题变成了"模拟 + 计数",无需推导公式也能得到高精度答案。
3. Generator API
(1) 为什么用 default_rng
NumPy 1.17 引入了全新的随机数体系——default_rng() 返回 Generator 对象,替代旧版 np.random.RandomState。
| 对比项 | Generator(新版) | RandomState(旧版) |
|---|---|---|
| 创建方式 | rng = np.random.default_rng() |
rng = np.random.RandomState() |
| 默认算法 | PCG64(高质量、快速) | MT19937(Mersenne Twister) |
| 流式设计 | 独立 Generator 实例,互不干扰 | 全局状态,np.random.seed() 影响全部 |
| 采样函数 | rng.integers()、rng.random() |
np.random.randint()、np.random.rand() |
| 可扩展性 | 支持自定义 BitGenerator | 不支持 |
| 推荐度 | ✅ 官方推荐 | ⚠️ 仅向后兼容 |
(2) default_rng 基本用法
PYTHON
import numpy as np
rng = np.random.default_rng()
# Float in [0, 1)
print(rng.random(5))
# [0.345 0.789 0.123 0.567 0.901]
# Integers in [low, high)
print(rng.integers(1, 7, size=10))
# [3 6 1 5 2 4 6 1 3 5]
# Standard normal
print(rng.standard_normal(5))
# [ 0.123 -1.456 2.345 0.789 -0.234]
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:Generator 基本用法(难度⭐)
PYTHON
import numpy as np
rng = np.random.default_rng(seed=42)
# Generate integers: dice rolls
dice = rng.integers(1, 7, size=20)
print("Dice rolls:", dice)
# Dice rolls: [1 2 2 2 6 3 4 5 1 3 5 2 6 6 1 5 6 5 2 3]
# Generate floats in [0, 1)
probs = rng.random(5)
print("Random probs:", probs)
# Random probs: [0.774 0.438 0.859 0.697 0.094]
# Generate 2D array
matrix = rng.integers(0, 100, size=(3, 4))
print("3x4 matrix:\n", matrix)
# 3x4 matrix:
# [[51 92 14 71]
# [60 20 82 86]
# [74 74 87 99]]
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
4. 常见分布
(1) 分布速查表
| 分布 | 方法 | 参数 | 值域 | 典型场景 |
|---|---|---|---|---|
| 均匀(连续) | rng.random(size) |
无([0,1)) | [0, 1) | 随机概率 |
| 均匀(整数) | rng.integers(low, high, size) |
low, high | [low, high) | 骰子、随机索引 |
| 正态 | rng.standard_normal(size) |
无(μ=0, σ=1) | (-∞, +∞) | 测量误差 |
| 正态(自定义) | rng.normal(loc, scale, size) |
μ, σ | (-∞, +∞) | 身高分布 |
| 二项 | rng.binomial(n, p, size) |
试验次数, 成功概率 | {0,1,...,n} | 抛硬币、骰子 |
| 泊松 | rng.poisson(lam, size) |
λ(期望) | {0,1,2,...} | 单位时间事件数 |
| 指数 | rng.exponential(scale, size) |
β=1/λ | [0, +∞) | 等待时间 |
| 对数正态 | rng.lognormal(mean, sigma, size) |
ln(X)的μ,σ | (0, +∞) | 收入分布 |
(2) 正态分布
正态分布是最常见的连续分布,参数 loc 是均值 μ,scale 是标准差 σ。
PYTHON
rng = np.random.default_rng(42)
# Standard normal: mu=0, sigma=1
data = rng.standard_normal(10000)
print(f"Mean: {data.mean():.4f}") # ≈ 0
print(f"Std: {data.std():.4f}") # ≈ 1
# Custom normal: mu=170, sigma=6 (heights in cm)
heights = rng.normal(loc=170, scale=6, size=10000)
print(f"Mean: {heights.mean():.2f} cm") # ≈ 170
print(f"Std: {heights.std():.2f} cm") # ≈ 6
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
(3) 均匀分布
PYTHON
rng = np.random.default_rng(42)
# Uniform floats in [0, 1)
u = rng.random(5)
print("Uniform [0,1):", u)
# Uniform floats in [a, b)
a, b = 10, 20
u_range = rng.uniform(a, b, size=5)
print(f"Uniform [{a},{b}):", u_range)
# Uniform integers in [low, high)
dice = rng.integers(1, 7, size=5) # 1~6
print("Dice:", dice)
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
(4) 二项分布与泊松分布
PYTHON
rng = np.random.default_rng(42)
# Binomial: flip 10 coins, count heads (p=0.5)
heads = rng.binomial(10, 0.5, size=5)
print("Heads out of 10 flips:", heads)
# e.g. [5 7 4 6 3]
# Poisson: average 3 events per interval
events = rng.poisson(lam=3, size=5)
print("Events per interval:", events)
# e.g. [2 4 1 5 3]
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:正态/均匀/二项(难度⭐⭐)
PYTHON
import numpy as np
rng = np.random.default_rng(seed=42)
# Normal distribution: simulate exam scores (mean=75, std=12)
scores = rng.normal(loc=75, scale=12, size=1000)
print(f"Scores - Mean: {scores.mean():.1f}, Std: {scores.std():.1f}")
print(f"Min: {scores.min():.1f}, Max: {scores.max():.1f}")
# Uniform distribution: random arrival times in [0, 60) minutes
arrivals = rng.uniform(0, 60, size=1000)
print(f"\nArrivals - Mean: {arrivals.mean():.1f} min (expect 30)")
# Binomial: 20-question true/false test, p=0.5
correct = rng.binomial(20, 0.5, size=1000)
print(f"\nCorrect answers - Mean: {correct.mean():.1f} (expect 10)")
print(f"Got all 20 right: {(correct == 20).sum()} times")
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
5. choice / shuffle / permute
(1) 采样函数对比
| 函数 | 作用 | 是否原地修改 | 返回值 |
|---|---|---|---|
rng.choice(a, size) |
从 a 中随机选取 | ❌ | 新数组 |
rng.shuffle(a) |
原地打乱顺序 | ✅ | None |
rng.permutation(a) |
返回打乱后的副本 | ❌ | 新数组 |
rng.permuted(a) |
沿指定轴打乱 | ❌ | 新数组 |
(2) choice 详解
PYTHON
rng = np.random.default_rng(42)
# Choose from list
fruits = rng.choice(["apple", "banana", "cherry"], size=5)
print("Random fruits:", fruits)
# Choose without replacement
lottery = rng.choice(range(1, 50), size=6, replace=False)
print("Lottery numbers:", sorted(lottery))
# Choose with weights
weighted = rng.choice(["A", "B", "C"], size=10, p=[0.5, 0.3, 0.2])
print("Weighted choice:", weighted)
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
(3) shuffle vs permutation
PYTHON
rng = np.random.default_rng(42)
# shuffle: in-place, returns None
a = np.arange(10)
result = rng.shuffle(a)
print("After shuffle, a =", a) # a is shuffled
print("shuffle returns:", result) # None
# permutation: returns new array, original unchanged
b = np.arange(10)
c = rng.permutation(b)
print("Original b =", b) # [0 1 2 3 4 5 6 7 8 9]
print("Permuted c =", c) # shuffled copy
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:choice/shuffle(难度⭐⭐)
PYTHON
import numpy as np
rng = np.random.default_rng(seed=42)
# Simulate drawing cards
deck = np.arange(52)
hand = rng.choice(deck, size=5, replace=False)
print("Poker hand:", hand)
# Shuffle and deal
deck_copy = np.arange(52)
rng.shuffle(deck_copy)
player1 = deck_copy[:13]
player2 = deck_copy[13:26]
print(f"Player 1 has {len(player1)} cards")
# Weighted sampling: biased coin (70% heads)
flips = rng.choice(["H", "T"], size=100, p=[0.7, 0.3])
heads_count = (flips == "H").sum()
print(f"Heads: {heads_count}/100 (expect ~70)")
# Permutation for train/test split
indices = rng.permutation(100)
train_idx = indices[:80]
test_idx = indices[80:]
print(f"Train: {len(train_idx)}, Test: {len(test_idx)}")
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
6. 随机种子与可复现
(1) 种子设哪
PYTHON
# ✅ Recommended: seed in default_rng
rng = np.random.default_rng(seed=42)
print(rng.random(3)) # reproducible
# ⚠️ Old style: global seed (affects all code)
# np.random.seed(42) # NOT recommended
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
最佳实践: 在 default_rng() 中设置种子,而非使用 np.random.seed()。前者只影响单个 Generator 实例,后者修改全局状态。
(2) 种子与可复现性
PYTHON
# Same seed → same sequence
rng1 = np.random.default_rng(seed=123)
rng2 = np.random.default_rng(seed=123)
print(rng1.integers(1, 100, size=5))
print(rng2.integers(1, 100, size=5))
# Both produce identical output!
# Different seed → different sequence
rng3 = np.random.default_rng(seed=456)
print(rng3.integers(1, 100, size=5))
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:种子/可复现(难度⭐)
PYTHON
import numpy as np
# Demonstrate reproducibility
def simulate_dice(seed, n=10):
rng = np.random.default_rng(seed=seed)
return rng.integers(1, 7, size=n)
# Same seed → identical results
a = simulate_dice(seed=42)
b = simulate_dice(seed=42)
print("Seed 42, run 1:", a)
print("Seed 42, run 2:", b)
print("Identical:", np.array_equal(a, b)) # True
# Different seed → different results
c = simulate_dice(seed=99)
print("Seed 99: ", c)
print("Identical:", np.array_equal(a, c)) # False
# Independent generators don't interfere
rng_a = np.random.default_rng(seed=1)
rng_b = np.random.default_rng(seed=1)
val_a = rng_a.random(3)
rng_a.random(100) # advance rng_a
val_b = rng_b.random(3)
print("rng_a first 3:", val_a)
print("rng_b first 3:", val_b)
print("Same:", np.array_equal(val_a, val_b)) # True
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
7. 蒙特卡洛模拟
(1) 蒙特卡洛 vs 解析解
| 对比项 | 蒙特卡洛 | 解析解 |
|---|---|---|
| 思路 | 大量随机模拟 → 统计频率 | 数学推导 → 精确公式 |
| 精度 | 随样本量增加,误差 ∝ 1/√N | 精确(无随机误差) |
| 适用范围 | 几乎任何概率问题 | 仅限可推导的问题 |
| 实现难度 | 低(模拟 + 计数) | 高(需数学功底) |
| 速度 | 需要大量样本才精确 | 一次计算得结果 |
(2) 蒙特卡洛模拟流程
graph TB
A["定义概率问题"] --> B["设计模拟方案"]
B --> C["生成大量随机样本"]
C --> D["统计目标事件频率"]
D --> E["频率 ≈ 概率"]
E --> F{"精度足够?"}
F -->|是| G["输出结果"]
F -->|否| C
style A fill:#4CAF50,color:#fff
style B fill:#2196F3,color:#fff
style C fill:#FF9800,color:#fff
style D fill:#9C27B0,color:#fff
style E fill:#E91E63,color:#fff
style G fill:#4CAF50,color:#fff
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
(3) 蒙特卡洛估算 π
单位正方形内画一个 1/4 圆,随机撒点,落在圆内的比例 ≈ π/4。
PYTHON
rng = np.random.default_rng(42)
N = 1_000_000
x = rng.random(N)
y = rng.random(N)
inside = (x**2 + y**2) <= 1.0
pi_estimate = 4 * inside.mean()
print(f"Estimated pi: {pi_estimate:.6f}")
print(f"Actual pi: {3.141593:.6f}")
print(f"Error: {abs(pi_estimate - 3.141593):.6f}")
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:蒙特卡洛 π(难度⭐⭐⭐)
PYTHON
import numpy as np
rng = np.random.default_rng(seed=42)
print("=== Monte Carlo Estimation of Pi ===\n")
for N in [1000, 10000, 100000, 1000000]:
x = rng.random(N)
y = rng.random(N)
inside = (x**2 + y**2) <= 1.0
pi_est = 4 * inside.mean()
error = abs(pi_est - np.pi)
print(f"N={N:>8,d} Pi≈{pi_est:.6f} Error={error:.6f}")
# N= 1,000 Pi≈3.116000 Error=0.025593
# N= 10,000 Pi≈3.139600 Error=0.001993
# N= 100,000 Pi≈3.141880 Error=0.000287
# N=1,000,000 Pi≈3.141268 Error=0.000325
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
8. PCG64 算法
(1) 为什么 PCG64 优于 MT19937
| 特性 | PCG64 | MT19937 |
|---|---|---|
| 周期 | 2^128 | 2^19937-1 |
| 统计质量 | 优秀(通过所有测试) | 存在已知缺陷 |
| 速度 | 快(~3 ns/样本) | 较慢(~4 ns/样本) |
| 状态大小 | 128 bit | 2.5 KB |
| 可预测性 | 难以预测输出 | 输出可部分预测 |
PCG64 是 default_rng() 的默认算法,无需手动指定。
PYTHON
# Explicit PCG64 (same as default)
from numpy.random import PCG64
rng = np.random.default_rng(PCG64(42))
# Use a different BitGenerator if needed
from numpy.random import Philox
rng_philox = np.random.default_rng(Philox(42))
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
9. 综合示例:蒙特卡洛估计
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:骰子概率 + 股价随机游走 + 生日悖论(难度⭐⭐⭐)
PYTHON
import numpy as np
rng = np.random.default_rng(seed=42)
# ========================================
# Part 1: Dice Probability
# ========================================
print("=== Part 1: Dice Probability ===\n")
# Q: Roll 1000 dice, probability of getting exactly 3 sixes?
N_sim = 100_000
sixes = rng.binomial(1000, 1/6, size=N_sim)
prob_3_sixes = (sixes == 3).mean()
print(f"P(exactly 3 sixes in 1000 rolls) ≈ {prob_3_sixes:.6f}")
# Analytical comparison
from math import comb
p_exact = comb(1000, 3) * (1/6)**3 * (5/6)**997
print(f"Analytical: {p_exact:.6f}")
# ========================================
# Part 2: Stock Price Random Walk
# ========================================
print("\n=== Part 2: Stock Price Random Walk ===\n")
# Geometric Brownian Motion
S0 = 100 # initial price
mu = 0.05 / 252 # daily drift (5% annual)
sigma = 0.2 / np.sqrt(252) # daily volatility (20% annual)
days = 252 # 1 year
n_paths = 5
for i in range(n_paths):
daily_returns = rng.normal(mu, sigma, size=days)
price_path = S0 * np.cumprod(1 + daily_returns)
final_price = price_path[-1]
print(f"Path {i+1}: Start={S0:.0f} → End={final_price:.2f} "
f"(Return={((final_price/S0)-1)*100:+.1f}%)")
# ========================================
# Part 3: Birthday Paradox
# ========================================
print("\n=== Part 3: Birthday Paradox ===\n")
# Q: In a room of N people, probability that at least 2 share a birthday?
def birthday_prob(n_people, n_sim=50_000):
rng_local = np.random.default_rng(42)
birthdays = rng_local.integers(1, 366, size=(n_sim, n_people))
has_duplicate = np.array([len(set(row)) < n_people for row in birthdays])
return has_duplicate.mean()
for n in [10, 23, 30, 40, 50, 70]:
prob = birthday_prob(n)
print(f"N={n:>2}: P(shared birthday) ≈ {prob:.3f}")
# N=23 is the famous threshold: ~50% chance!
TEXT
📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
❓ 常见问题
Q 为什么用 default_rng 而不是 np.random.rand?
A
default_rng() 返回独立 Generator 实例,流式设计互不干扰;np.random.rand() 依赖全局状态,多线程或多次调用时会互相影响。新版 API 还默认使用更高质量的 PCG64 算法。Q 随机种子应该设在哪?
A 在
default_rng(seed=42) 中设置,而非 np.random.seed(42)。前者只影响该 Generator 实例,后者修改全局状态。开发/调试时固定种子保证可复现,生产环境可省略种子获取真随机。Q 正态分布的 loc 和 scale 参数怎么理解?
A
loc 是均值 μ(数据中心位置),scale 是标准差 σ(数据离散程度)。约 68% 的值落在 μ±σ 内,95% 落在 μ±2σ 内。standard_normal() 等价于 normal(loc=0, scale=1)。Q 蒙特卡洛精度与样本量有什么关系?
A 误差 ∝ 1/√N。样本量增加 100 倍,误差只缩小 10 倍。例如 N=10000 时误差约 0.01,N=1000000 时误差约 0.001。需要更高精度只能增加样本量。
Q choice 的权重参数 p 怎么用?
A
p 是概率数组,必须与候选数组等长且和为 1。例如 rng.choice(["A","B","C"], p=[0.5,0.3,0.2]) 表示 A 被选中概率 50%,B 30%,C 20%。不设 p 则等概率选取。Q shuffle 和 permutation 怎么选?
A 需要原地打乱用
shuffle(不额外占用内存,返回 None);需要保留原数组用 permutation(返回打乱后的副本,原数组不变)。多数场景 permutation 更安全。📖 小节
default_rng()创建 Generator 实例,推荐替代旧版全局np.random- PCG64 是默认高质量算法,无需手动指定
- 常见分布:
random()(均匀)、normal()(正态)、binomial()(二项)、poisson()(泊松) choice随机选取(支持权重),shuffle原地打乱,permutation返回打乱副本- 种子设在
default_rng(seed=...)中,保证可复现且不影响全局 - 蒙特卡洛:模拟 + 计数,误差 ∝ 1/√N,适用于复杂概率问题
📝 作业
(1) 硬币概率估计
- 用
default_rng(seed=0)创建 Generator - 模拟 100000 次抛 10 枚硬币,统计每次正面数量(
binomial(10, 0.5)) - 估算"恰好 5 枚正面"的概率
- 与解析值
comb(10,5) * 0.5**10 ≈ 0.246对比,计算误差
(2) 1000 天股价随机游走
- 初始价格 S0=50,日漂移 μ=0.0003,日波动 σ=0.02
- 用
rng.normal(mu, sigma, size=1000)生成日收益率 - 用
np.cumprod(1 + returns)计算价格路径 - 绘制/打印第 1、100、500、1000 天的价格
- 重复 1000 次模拟,统计最终价格的中位数和均值
(3) 验证大数定律
- 用
rng.random()生成 N 个 [0,1) 均匀随机数 - 对 N = 10, 100, 1000, 10000, 100000, 1000000 分别计算样本均值
- 打印每个 N 的均值与理论均值 0.5 的偏差
- 观察偏差随 N 增大而趋近 0(大数定律)