统计函数
基本统计量
import numpy as np arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) # 集中趋势 print(arr.mean()) # 5.5(均值) print(np.mean(arr)) # 同上(函数形式) print(np.median(arr)) # 5.5(中位数) print(np.average(arr)) # 5.5(加权平均,可传 weights) # 分位数 print(np.percentile(arr, 25)) # 3.25(第 25 百分位) print(np.percentile(arr, 50)) # 5.5(= 中位数) print(np.percentile(arr, 75)) # 7.75 print(np.quantile(arr, 0.25)) # 同上(0~1 之间) print(np.quantile(arr, [0.25, 0.5, 0.75])) # 一次算多个 # 离散程度 print(arr.std()) # 2.87(标准差) print(arr.var()) # 8.25(方差) print(np.ptp(arr)) # 9(极差 = max - min) # 极值 print(arr.min()) # 1 print(arr.max()) # 10 print(arr.sum()) # 55 # 累积 print(arr.cumsum()) # [1 3 6 10 15 21 28 36 45 55](前缀和) print(arr.cumprod()) # 累积乘积
沿轴向统计
mat = np.arange(12).reshape(3, 4) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # axis=0: 沿行方向(压缩行,对每列操作) print(mat.sum(axis=0)) # [12 15 18 21] — 每列求和 print(mat.mean(axis=0)) # [4. 5. 6. 7.] — 每列均值 print(mat.max(axis=0)) # [ 8 9 10 11] — 每列最大值 # axis=1: 沿列方向(压缩列,对每行操作) print(mat.sum(axis=1)) # [ 6 22 38] — 每行求和 print(mat.mean(axis=1)) # [1.5 5.5 9.5] — 每行均值 # keepdims: 保持维度 print(mat.sum(axis=1, keepdims=true)) # (3, 1) 而非 (3,) # [[ 6] # [22] # [38]]
轴向统计示意图
axis=0 沿行方向(垂直向下)→ 压缩行,得到每列的统计 axis=1 沿列方向(水平向右)→ 压缩列,得到每行的统计 axis 小口诀: axis=0 是"纵向压扁", axis=1 是"横向压扁"
高级统计函数
arr = np.array([1, 2, 3, 4, 5, 6]) # 相关系数 x = np.array([1, 2, 3, 4, 5]) y = np.array([2, 4, 5, 4, 5]) print(np.corrcoef(x, y)) # [[1. 0.774597] # [0.774597 1. ]] # 直方图(计数) hist, bin_edges = np.histogram(arr, bins=3) print(hist) # [2 2 2] print(bin_edges) # [1. 2.667 4.333 6. ] # 数字化(找每个值落入哪个 bin) bins = np.array([0, 3, 7, 10]) print(np.digitize([1, 5, 8, 9], bins)) # [1 2 3 3] # 加权平均 values = np.array([1, 2, 3, 4]) weights = np.array([0.1, 0.2, 0.3, 0.4]) print(np.average(values, weights=weights)) # 3.0 # 协方差 print(np.cov(x, y)) # 差异 print(np.diff(arr)) # [1 1 1 1 1] — 相邻差 print(np.diff(arr, n=2)) # [0 0 0 0] — 二阶差分 # 梯度(多维偏导) mat = np.array([[1, 2, 6], [3, 4, 5]]) print(np.gradient(mat)) # 每个维度的梯度 # 排序 print(np.sort([3, 1, 4, 1, 5])) # [1 1 3 4 5] arr = np.array([3, 1, 4, 1, 5]) arr.sort() # 原地排序 # argsort: 返回排序后的索引 idx = np.argsort([3, 1, 4, 1, 5]) print(idx) # [1 3 0 2 4] — 按值排序后的原索引 # argmax / argmin: 极值索引 arr = np.array([10, 5, 30, 20]) print(arr.argmax()) # 2(最大值 30 的位置) print(arr.argmin()) # 1(最小值 5 的位置) # nan 安全版本 arr = np.array([1.0, np.nan, 3.0, np.nan, 5.0]) print(np.nanmean(arr)) # 3.0(忽略 nan) print(np.nanstd(arr)) # 忽略 nan 的标准差 print(np.nansum(arr)) # 忽略 nan 的求和 print(np.nan_to_num(arr, nan=0)) # nan → 0: [1. 0. 3. 0. 5.]
线性代数(np.linalg)
a = np.array([[1, 2],
[3, 4]])
b = np.array([[5, 6],
[7, 8]])
矩阵基本运算
# 矩阵乘法 print(a @ b) print(np.dot(a, b)) print(np.matmul(a, b)) # 矩阵求逆 print(np.linalg.inv(a)) # [[-2. 1. ] # [ 1.5 -0.5]] # 矩阵的幂 print(np.linalg.matrix_power(a, 3)) # a @ a @ a # 行列式 print(np.linalg.det(a)) # -2.0 # 迹 print(np.trace(a)) # 1 + 4 = 5 # 转置 print(a.t) # 秩 print(np.linalg.matrix_rank(a)) # 2 # 条件数 print(np.linalg.cond(a))
特征值与特征向量
eigenvalues, eigenvectors = np.linalg.eig(a)
print(eigenvalues) # [-0.3723 5.3723]
print(eigenvectors)
# 验证: a·v = λ·v
for i in range(len(eigenvalues)):
av = a @ eigenvectors[:, i]
lv = eigenvalues[i] * eigenvectors[:, i]
print(np.allclose(av, lv)) # true
svd(奇异值分解)
u, s, vt = np.linalg.svd(a) print(u.shape, s.shape, vt.shape) # (2,2) (2,) (2,2) # 重构: a = u @ diag(s) @ vt a_reconstructed = u @ np.diag(s) @ vt print(np.allclose(a, a_reconstructed)) # true
解线性方程组
# 解 ax = b a = np.array([[3, 1], [1, 2]]) b = np.array([9, 8]) x = np.linalg.solve(a, b) print(x) # [2. 3.] print(a @ x) # [9. 8.] ✓ # 最小二乘解(超定/欠定方程组) a = np.array([[1, 1], [1, 2], [1, 3]]) b = np.array([1, 2, 2]) x, residuals, rank, s = np.linalg.lstsq(a, b, rcond=none) print(x) # [0.6667 0.5 ] — 最佳拟合
范数
v = np.array([3, 4]) print(np.linalg.norm(v)) # l2: 5.0 (默认) print(np.linalg.norm(v, ord=1)) # l1: 7.0 print(np.linalg.norm(v, ord=np.inf)) # l∞: 4.0 # 矩阵范数 print(np.linalg.norm(a, ord='fro')) # frobenius: sqrt(1²+2²+3²+4²) print(np.linalg.norm(a, ord=2)) # 谱范数(最大奇异值)
其他 linalg 函数
# qr 分解 q, r = np.linalg.qr(a) # cholesky 分解(需对称正定) a_spd = np.array([[4, 1], [1, 3]]) l = np.linalg.cholesky(a_spd) print(l @ l.t) # 等于 a_spd # lu 分解 from scipy.linalg import lu # scipy 提供更完整的分解 # 张量点积 a = np.arange(24).reshape(2, 3, 4) b = np.arange(20).reshape(4, 5) print(np.tensordot(a, b, axes=([2], [0])).shape) # (2, 3, 5)
随机数模块
新版 api(推荐)—np.random.default_rng()
# 创建随机数生成器 rng = np.random.default_rng(seed=42) # 均匀分布 rng.uniform(0, 1, 10) # [0,1) 均匀 rng.integers(0, 100, 10) # [0,100) 整数 rng.random(10) # 等同于 uniform(0, 1) # 正态分布 rng.standard_normal((3, 4)) # n(0, 1) rng.normal(loc=5, scale=2, size=(3, 4)) # n(5, 4) # 其他分布 rng.exponential(scale=1.0, size=10) # 指数分布 rng.poisson(lam=3, size=10) # 泊松分布 rng.binomial(n=10, p=0.5, size=10) # 二项分布 rng.chisquare(df=2, size=10) # 卡方分布 rng.gamma(shape=2, scale=1, size=10) # gamma 分布 rng.beta(a=2, b=5, size=10) # beta 分布 rng.laplace(loc=0, scale=1, size=10) # 拉普拉斯分布 rng.lognormal(mean=0, sigma=1, size=10) # 对数正态 # 排列与抽样 arr = np.array([1, 2, 3, 4, 5]) rng.shuffle(arr) # 原地打乱 print(rng.permutation(arr)) # 返回打乱副本 print(rng.choice(arr, size=3, replace=false)) # 不放回抽样 print(rng.choice(arr, size=10, replace=true)) # 有放回抽样 print(rng.choice(arr, size=3, p=[0.1, 0.1, 0.3, 0.3, 0.2])) # 带概率
旧版 api(兼容)—np.random.
# 旧版(全局状态,不推荐新代码使用) np.random.seed(42) np.random.rand(3, 4) # [0,1) 均匀 np.random.randn(3, 4) # n(0,1) np.random.randint(0, 100, (3, 4)) # 整数 np.random.normal(0, 1, (3, 4)) # 正态 np.random.uniform(0, 1, (3, 4)) # 均匀 np.random.shuffle(arr) # 打乱 np.random.choice(arr, 5) # 抽样
固定随机种子(可复现)
# 新版 rng = np.random.default_rng(42) result1 = rng.normal(0, 1, 1000) # 旧版 np.random.seed(42) result2 = np.random.randn(1000) # 确保整个程序的随机性都可复现 random_seed = 42 rng = np.random.default_rng(random_seed)
速查表
| 需求 | 代码 |
|---|---|
| 均值 | arr.mean() / np.mean(arr) |
| 中位数 | np.median(arr) |
| 标准差 | arr.std() |
| 方差 | arr.var() |
| 总和 | arr.sum() |
| 沿轴求和 | arr.sum(axis=0) |
| 分位数 | np.percentile(arr, 50) |
| 最小值索引 | arr.argmin() |
| 最大值索引 | arr.argmax() |
| 相邻差 | np.diff(arr) |
| 排序索引 | np.argsort(arr) |
| 相关系数 | np.corrcoef(x, y) |
| 直方图 | np.histogram(arr, bins=10) |
| nan 安全均值 | np.nanmean(arr) |
| 矩阵乘法 | a @ b |
| 求逆 | np.linalg.inv(a) |
| 行列式 | np.linalg.det(a) |
| 特征值 | np.linalg.eig(a) |
| svd | np.linalg.svd(a) |
| 解方程 | np.linalg.solve(a, b) |
| 范数 | np.linalg.norm(v) |
| 随机种子 | rng = np.random.default_rng(42) |
| 正态分布 | rng.standard_normal(shape) |
| 均匀分布 | rng.uniform(0, 1, shape) |
| 打乱 | rng.shuffle(arr) |
| 抽样 | rng.choice(arr, size=5) |
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论