NumPy 快速入门与实战教程(逐行拆解 + 专业扩展)
NumPy 快速入门与实战教程
(基于你给出的完整代码,逐行拆解 + 专业扩展)
====================================================================
0. 前置知识
• NumPy 的核心数据结构是 ndarray(N 维数组)。
• 与 Python 原生 list 相比,ndarray 在内存布局上连续、类型单一,因此
– 占用内存更小
– 支持向量化运算(无显式 for-loop,速度提升 10~100×)
– 拥有广播(broadcasting)机制,可隐式扩展维度。
====================================================================
- 创建 ndarray
1.1 从 Python 序列构造
import numpy as np
arr = np.array([1, 2, 3])
print(arr) # [1 2 3]
• 一维数组 shape=(3,)。
• dtype 自动推断为 int64(或 int32,取决于平台)。
1.2 二维及高维
arr = np.array([[1, 2, 3],[4, 5, 6]])
print(arr.shape) # (2, 3) -> 2 行 3 列
print(arr.size) # 6 -> 元素总数
print(arr.dtype) # int64
print(arr.T) # 转置,shape=(3, 2)
• .T
等价于 np.transpose(arr)
,O(1) 时间复杂度(仅改变 strides)。
====================================================================
2. 数组的深拷贝
arr1 = np.copy(arr)
• np.copy
会分配新内存,避免“视图”带来的副作用。
• 如果只是 arr1 = arr
,则 arr1
是原数组的视图,共享底层数据。
====================================================================
3. 占位符 & 常值构造器
函数 | 语义 | 示例 |
---|---|---|
zeros | 全 0 | np.zeros((3,4)) |
ones | 全 1 | np.ones((3,4), dtype=int) |
empty | 未初始化(值随机) | np.empty((3,4)) |
full | 指定常值 | np.full((3,4), 10) |
eye | 单位矩阵 | np.eye(5, 5, dtype=int) |
diag | 对角矩阵 | np.diag([1,2,3]) |
- 全 0 数组
import numpy as np
a = np.zeros((3, 4)) # 默认 float64
print(a, a.dtype)
# [[0. 0. 0. 0.]
# [0. 0. 0. 0.]
# [0. 0. 0. 0.]] float64
- 全 1 数组
b = np.ones((2, 3), dtype=int) # 指定 int 类型
print(b)
# [[1 1 1]
# [1 1 1]]
- 未初始化(内容随机残留)
c = np.empty((2, 2))
print(c) # 数值不可预期,仅分配内存
- 指定常值填充
d = np.full((4, 1), 7.5) # 任意标量 7.5
print(d)
# [[7.5]
# [7.5]
# [7.5]
# [7.5]]
- 单位矩阵
e = np.eye(4, 4, k=0, dtype=int) # k=0 主对角线;k>0 上偏移,k<0 下偏移
print(e)
# [[1 0 0 0]
# [0 1 0 0]
# [0 0 1 0]
# [0 0 0 1]]
- 对角矩阵
f = np.diag([10, 20, 30]) # 1-D → 2-D 对角方阵
print(f)
# [[10 0 0]
# [ 0 20 0]
# [ 0 0 30]]
- 从已有矩阵提取对角线
g = np.arange(9).reshape(3, 3)
diag_vals = np.diag(g) # 2-D → 1-D
print(diag_vals) # [0 4 8]
运行顺序无依赖,可单独测试。
====================================================================
4. 规则序列
4.1 等差数列
arr = np.arange(1, 10, 2) # [1 3 5 7 9]
# 左闭右开,步长 2
4.2 等间隔数列
arr = np.linspace(1, 10, 4, dtype=int) # [ 1 4 7 10]
# 在闭区间 [1,10] 内产生 4 个等距点,支持 endpoint=True/False
4.3 对数间隔数列
arr = np.logspace(1, 10, 4, base=2, dtype=int)
# [ 2 8 32 512] -> 2^1, 2^(10/3), 2^(20/3), 2^10
====================================================================
5. 随机数组
函数 | 分布 | 用法示例 |
---|---|---|
rand | U(0,1) 均匀 | np.random.rand(2,5) |
randint | 离散均匀 | np.random.randint(low, high, size) |
randn | 标准正态 N(0,1) | np.random.randn(2,6) |
可重复随机:
np.random.seed(20) # 设置全局随机种子
arr = np.random.randint(2, 5, (2, 5))
====================================================================
6. 索引、切片与布尔筛选
6.1 一维
arr = np.random.randint(1, 100, 10)
print(arr[1:5]) # 左闭右开
print(arr[(arr>10) & (arr<50)]) # 布尔掩码
6.2 二维
arr = np.random.randint(1, 100, (4, 8))
print(arr[1:3, 1:3]) # 行列切片
• 切片返回的是“视图”,与原数组共享内存。
• 布尔索引返回的是“拷贝”。
====================================================================
7. 广播机制(Broadcasting)
规则:从尾部维度开始比较
- 维度长度相等,或
- 其中一维长度为 1(可扩展)
示例 1:
a = np.array([[1,2,3],[4,5,6]]) # shape=(2,3)
b = np.array([[7,8,9]]) # shape=(1,3)
print(a + b) # 自动扩展 b -> (2,3)
示例 2:
m = np.array([1,2,3]) # shape=(3,)
n = np.array([[4],[5],[6]]) # shape=(3,1)
print(m + n) # 两者分别扩展为 (3,3)
====================================================================
8. 统计函数
np.random.seed(0)
arr = np.random.randint(1, 10, 4) # 固定随机种子
print(np.sum(arr))
print(np.mean(arr)) # 算术平均
print(np.median(arr)) # 中位数
print(np.percentile(arr, 25)) # 第 25 百分位
print(np.var(arr)) # 方差 (ddof=0 默认总体方差)
print(np.std(arr)) # 标准差
累积函数:
arr = np.array([1,2,3])
print(np.cumsum(arr)) # [1 3 6]
print(np.cumprod(arr)) # [1 2 6]
====================================================================
9. 形状操作
9.1 拼接
arr1 = np.array([1,2,3])
arr2 = np.array([4,5,6])
print(np.concatenate((arr1, arr2))) # [1 2 3 4 5 6]
二维拼接需指定 axis
。
9.2 reshape
np.random.seed(0)
arr = np.random.randint(1, 10, (4, 5)) # shape=(4,5)
arr2 = np.reshape(arr, (1, 20)) # 平铺
# 等价写法: arr.reshape(1, -1) 或 arr.ravel()
• reshape 返回视图(若内存连续)。
• -1
表示自动推断该维度大小。
====================================================================
10. 性能提示
• 避免 Python 级 for-loop,优先使用向量化 ufunc。
• 大量小数组会带来 Python 对象开销,尽量一次性分配大数组。
• np.empty
+ 后续赋值 比 np.zeros
更快,但需确保覆盖所有元素。
• 使用 out=
参数重用缓冲区,减少额外内存分配。
例:np.add(a, b, out=a)
。
====================================================================
11. 完整思维导图(文字版)
创建 → 初始化(zeros/ones/full/empty)
→ 序列(arange/linspace/logspace)
→ 随机(rand/randint/randn)
→ 特殊(eye/diag)
操作 → 索引/切片 → 布尔筛选
→ 形状变换(reshape/concatenate)
→ 广播运算
→ 统计/聚合
性能 → 向量化
→ 视图 vs 拷贝
→ 预分配内存
====================================================================
12. 小结
掌握 ndarray 的内存模型与广播规则,即掌握了 90% 的日常 NumPy 用法。
后续可继续学习:
• 广义 ufunc(np.matmul
, np.einsum
)
• 结构化数组(structured array)
• 掩码数组(masked array)
• 与 Pandas / SciPy / scikit-learn 协同。
祝你编码愉快!