NumPy 第 1 章:创建数组

本系列是《NumPy 速通》的配套章节。速通是主线,这里是细节。 一切 NumPy 代码的起点:怎么把数据变成 ndarray。本章覆盖所有主流创建方式,以及创建时最容易踩的坑。 从列表 / 元组创建:np.array 把已有的 Python 序列变成 ndarray,用 np.array() 包一下就行: import numpy as np # 一维:从列表 scores = np.array([88, 92, 76, 85, 90]) print(scores) # [88 92 76 85 90] print(type(scores)) # <class 'numpy.ndarray'> print(scores.dtype) # int64 元素类型 # 从元组也可以 t = np.array((1, 2, 3)) # [1 2 3] # 二维:嵌套列表 = 表格(行=同学,列=科目) table = np.array([[88, 92, 76], [85, 90, 91], [77, 82, 95]]) print(table.shape) # (3, 3) 打印出来和列表差不多,但底层完全不同:ndarray 把同类型数字紧密排列在连续内存中,运算效率高出几十倍。 np.array 的关键参数 np.array([1, 2, 3], dtype=np.float64) # 指定元素类型 np.array([1, 2, 3], ndmin=2) # 强制至少 2 维 → [[1 2 3]] np.array([1, 2, 3], copy=True) # 强制复制一份(默认也是复制) ⚠️ 嵌套列表必须"整齐" np.array([[1, 2], [3]]) # ❌ 报错:各行长度不一致,无法构成矩形 # ValueError: setting an array element with a sequence. 创建矩阵/表格时,每行长度必须相同,否则 NumPy 不知道往哪个维度放。 ...

2026-08-30 · OC

NumPy 第 10 章:数组拼接与分割

本系列是《NumPy 速通》的配套章节。 把多个数组合并(拼接),或者把一个数组拆开(分割)——数据处理和特征工程里很常用。本章核心:concatenate(通用)、vstack/hstack(直观)、split(分割),以及一个灵魂警告:拼接出的新数组和原数组的关系。 拼接:concatenate(最通用的一个) import numpy as np a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) np.concatenate([a, b]) # [1 2 3 4 5 6] 一维:直接接一起 np.concatenate([a, b, a])# [1 2 3 4 5 6 1 2 3] 可以传多个 二维数组可以指定沿行还是沿列拼: x = np.array([[1, 2], [3, 4]]) y = np.array([[5, 6], [7, 8]]) np.concatenate([x, y], axis=0) # 沿行方向拼 → 上下堆叠 (4,2) # [[1 2] # [3 4] # [5 6] # [7 8]] np.concatenate([x, y], axis=1) # 沿列方向拼 → 左右拼接 (2,4) # [[1 2 5 6] # [3 4 7 8]] ⚠️ 灵魂警告:拼接的数组必须"形状兼容"。 axis=0 拼接:除第 0 维外,其余维度必须相等(列数要一样) axis=1 拼接:行数要一样 违反则报 ValueError: all the input array dimensions ... must match 常见场景:两个数据集的列数不一样(一个多了个特征列)→ 想按行拼会报错,先对齐列。 ...

2026-08-30 · OC

NumPy 第 11 章:文件读写

本系列是《NumPy 速通》的配套章节。 把数组保存到磁盘,下次直接加载——省去每次重新计算的麻烦。本章覆盖三种格式:.npy(二进制、单个)、.npz(多个)、文本(CSV/TXT 交换用),外加加载时的**allow_pickle 陷阱**。 保存 / 加载单个数组 import numpy as np arr = np.array([1, 2, 3, 4, 5]) np.save("arr.npy", arr) # 保存,自动加 .npy 后缀 loaded = np.load("arr.npy") # 加载 print(loaded) # [1 2 3 4 5] .npy 是 NumPy 专有格式,保存的是二进制,会连 dtype、shape 一起存下来,加载回来原样还原(类型、形状都不丢)。 保存多个数组:npz 一个文件里存多个数组: a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) np.savez("data.npz", a=a, b=b) # 存多个,自动加 .npz data = np.load("data.npz") data["a"] # array([1, 2, 3]) data["b"] # array([4, 5, 6]) 加载 .npz 得到的是一个类字典对象(NpzFile),用键名取值。 💡 savez_compressed:np.savez_compressed("data.npz", a=a, b=b) 用压缩存储,文件更小(适合大数据、文本类数据),代价是读写稍慢。 文本格式:与外部工具交换 需要和其他语言/工具交换数据时,用文本格式(CSV): np.savetxt("arr.csv", arr, delimiter=",") # 存成 CSV np.loadtxt("arr.csv", delimiter=",") # 读回 savetxt / loadtxt 常用参数 # 保存:可以加表头、控制格式 np.savetxt("data.csv", data, delimiter=",", header="col1,col2,col3", # 表头 fmt="%.2f") # 保留 2 位小数 # 读取:跳过表头、跳过某列 np.loadtxt("data.csv", delimiter=",", skiprows=1, # 跳过第 1 行表头 dtype=float) ⚠️ 用 genfromtxt 处理"缺数据"的文本 # loadtxt 遇缺数据会报错 np.loadtxt("messy.csv", delimiter=",") # ❌ 某格为空 → ValueError # genfromtxt 更宽容:缺失的填 nan data = np.genfromtxt("messy.csv", delimiter=",") np.isnan(data).any() # True → 有缺失,处理掉(第 9 章) genfromtxt 是 loadtxt 的加强版,缺数据不崩、自动转 nan,处理真实脏数据用它。 ...

2026-08-30 · OC

NumPy 第 12 章:随机数

本系列是《NumPy 速通》的配套章节。 生成随机数——初始化参数、模拟数据、打乱顺序都靠它。本章核心:新接口 default_rng、种子可复现、常用分布、以及"随机打乱 vs 抽样"。 推荐用法:default_rng(NumPy 1.17+) import numpy as np rng = np.random.default_rng(42) # 传入种子,结果可复现 default_rng 是 NumPy 新推荐的接口(1.17+),比老的 np.random.rand() / np.random.seed() 更好: 老接口(不推荐) 新接口(推荐) np.random.seed(42) 全局设置 rng = np.random.default_rng(42) 独立对象 np.random.rand(5) rng.random(5) np.random.randint(0, 10) rng.integers(0, 10) np.random.normal(0, 1) rng.normal(0, 1) 💡 老接口是全局状态(影响整个程序);新接口每个 rng 是独立的随机源——多线程、多模块不互相干扰,是现代推荐写法。 常用随机函数 rng = np.random.default_rng(42) rng.random(5) # 均匀分布 [0,1),一维 5 个 rng.random((2, 3)) # 均匀分布,2 行 3 列 rng.normal(0, 1, 10) # 正态分布(均值 0,标准差 1) rng.integers(0, 10, 5) # 0~9 的随机整数,5 个 rng.permutation(10) # 0~9 的随机排列 rng.uniform(0, 10, 5) # 均匀分布 [0,10) rng.choice([1,2,3,4,5], size=3) # 从列表随机抽 3 个 rng.choice([1,2,3,4,5], size=3, replace=False) # 不重复抽样 ⭐ 种子(seed)的作用:可复现性 rng1 = np.random.default_rng(42) rng2 = np.random.default_rng(42) rng1.random(3) # [0.37454012 0.95071431 0.73199394] rng2.random(3) # [0.37454012 0.95071431 0.73199394] 一样! 传同样的种子 → 生成同样的序列。这保证了实验可复现: ...

2026-08-30 · OC

NumPy 第 13 章:线性代数基础

本系列是《NumPy 速通》的配套章节。 线性代数是 NumPy 的"根"——NumPy 本来就是为科学计算而生的。矩阵乘法、求逆、解方程组、特征值,在机器学习、图像处理、物理模拟中无处不在。 本章只讲 np.linalg 里最常用的函数,你不需要是数学专家,理解"做什么、什么时候用"就够了。 矩阵乘法:@ vs *(先复习这一课) 最重要的一课:* 是逐元素乘法,@ 才是矩阵乘法(点积)。 import numpy as np A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6], [7, 8]]) A * B # 逐元素乘法 # [[ 5 12] # [21 32]] A @ B # 矩阵乘法(行 × 列) # [[19 22] # [43 50]] np.dot(A, B) # 和 @ 等价 ⚠️ 灵魂警告(再次强调):用错符号结果完全不同。 @ 要求内维相等:(m,n) @ (n,k) → (m,k) 一维向量 @:np.dot([1,2,3], [4,5,6]) → 标量 32(内积) 神经网络前向传播 W @ x、线性回归 X @ theta 都用 @ 常用线性代数函数总览 np.linalg.inv(A) # 逆矩阵(A @ inv(A) = I) np.linalg.det(A) # 行列式(判断是否可逆、体积缩放) np.linalg.eig(A) # 特征值 & 特征向量 np.linalg.solve(A, b) # 解线性方程组 A x = b(推荐) np.linalg.norm(v) # 向量的模长 np.linalg.matrix_rank(A)# 矩阵的秩 np.linalg.qr(A) # QR 分解 np.linalg.svd(A) # 奇异值分解(SVD,压缩/降维核心) 解方程组:np.linalg.solve # 2x + 3y = 8 # x + y = 3 A = np.array([[2, 3], [1, 1]]) b = np.array([8, 3]) x = np.linalg.solve(A, b) # [1. 2.] 即 x=1, y=2 为什么用 solve 而不是 inv(A) @ b? ...

2026-08-30 · OC

NumPy 第 2 章:数组属性

本系列是《NumPy 速通》的配套章节。 拿到一个数组,第一件事往往是"体检":它多大?几维?里面是什么类型?这四个属性搞明白,后面所有广播、axis、运算的坑都能绕开一大半。 import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6]]) arr.shape # (2, 3) 每个维度的大小 arr.ndim # 2 维度数量 arr.size # 6 元素总个数 arr.dtype # int64 元素的数据类型 arr.itemsize # 8 每个元素占多少字节 arr.nbytes # 48 整个数组占多少字节(size × itemsize) shape —— 形状(最重要) (2, 3) 表示 2 行 3 列。一切数组运算的前提都是搞清楚 shape——广播、axis、reshape 全围绕它转。 np.array([1, 2, 3]).shape # (3,) 一维,注意结尾逗号! np.array([[1, 2, 3]]).shape # (1, 3) 一行三列 np.array([[1], [2], [3]]).shape # (3, 1) 三行一列 np.zeros((2, 3, 4)).shape # (2, 3, 4) 三维 ⚠️ 灵魂警告:(3,) 和 (3, 1) 和 (1, 3) 长度都写"3",但完全不同——一个是向量,一个是列,一个是行。这直接决定广播行为(第 8 章)。看到 shape 时永远要留意是不是一维。 ...

2026-08-30 · OC

NumPy 第 3 章:索引与切片

本系列是《NumPy 速通》的配套章节。 索引和切片就是"从数组中取东西",是使用频率最高的操作。一维和 Python 列表几乎一样,关键是多维用逗号分隔各维度,还有最容易被误伤的花式索引和"视图"问题。 一维数组的索引与切片 import numpy as np arr = np.array([10, 20, 30, 40, 50, 60, 70, 80]) # —— 单点索引 —— arr[0] # 10 第一个元素(从 0 开始) arr[-1] # 80 最后一个 arr[-2] # 70 倒数第二个 # —— 切片:arr[start:stop:step] —— arr[1:4] # [20 30 40] 索引 1,2,3(不包含 4) arr[:3] # [10 20 30] 从开头到索引 2 arr[3:] # [40 50 60 70 80] 从索引 3 到最后 arr[::2] # [10 30 50 70] 每隔一个取一个 arr[::-1] # [80 70 60 50 40 30 20 10] 倒序 arr[::-2] # [80 60 40 20] 倒序且隔一个 规则:[start:stop:step],start 包含、stop 不包含。省略 start 默认 0,省略 stop 默认末尾,省略 step 默认 1。负 step 表示反向。 ...

2026-08-30 · OC

NumPy 第 4 章:数组运算

本系列是《NumPy 速通》的配套章节。 NumPy 最大的魅力:数组可以直接做数学运算,而且是逐元素的(element-wise),不需要写循环。本章讲透四类运算:算术、标量、比较、* vs @,以及"就地运算"这个高效技巧。 逐元素算术运算 import numpy as np a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) a + b # [5 7 9] 加法(对应位置相加) a - b # [-3 -3 -3] 减法 a * b # [4 10 18] 乘法 a / b # [0.25 0.4 0.5 ] 除法(结果是浮点) a // b # [0 0 0] 整除 a % b # [1 2 3] 取余 a ** 2 # [1 4 9] 乘方 -a # [-1 -2 -3] 取负 两个数组形状相同 → 对应位置逐个算,这就是"逐元素"(element-wise)。不需要写 for i in range(len(a))——这正是 NumPy 快的原因。 运算符 ↔ ufunc 对应表 运算符 对应 ufunc + np.add - np.subtract * np.multiply / np.divide ** np.power > < == 等 np.greater 等 运算符是 ufunc 的"语法糖",二者等价。底层都是 C 实现的 ufunc(第 6 章详述)。 ...

2026-08-30 · OC

NumPy 第 5 章:形状操作

本系列是《NumPy 速通》的配套章节。 调整数组的"长相"——重塑、展平、转置、增删维度,是数据处理和喂给模型的必经步骤。核心心法:shape 变了,但底层数据(和顺序)没变。 reshape —— 重塑形状 不改变元素个数,只改变排列方式。注意顺序:按行优先(C 顺序)逐行填充: import numpy as np arr = np.arange(12) # [0 1 2 3 4 5 6 7 8 9 10 11] arr.reshape(3, 4) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] arr.reshape(4, 3) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11]] arr.reshape(2, 6) # 2 行 6 列 -1 让 NumPy 自动算维度 arr.reshape(2, -1) # 自动算出 6 列 → (2, 6) arr.reshape(-1, 3) # 自动算出 4 行 → (4, 3) arr.reshape(-1) # 展平成一维(等价的另一种写法) -1 只能出现一次(否则无法确定)。 ...

2026-08-30 · OC

NumPy 第 6 章:通用函数(ufunc)

本系列是《NumPy 速通》的配套章节。 通用函数(universal function,简称 ufunc)就是对数组逐元素应用数学运算的函数。它们由 C 语言实现,一次性遍历整个数组,比 Python 循环快几十上百倍。本章讲透:一元/二元 ufunc 有哪些、nan 陷阱、out= 省内存、以及"向量化思维"。 常用一元 ufunc(一个数组 → 一个数组) import numpy as np arr = np.array([-1, 0, 1, 2, 4]) np.abs(arr) # [1 0 1 2 4] 绝对值 np.sqrt(arr) # [nan 0. 1. 1.414 2.] 开平方(负数→nan) np.square(arr) # [1 0 1 4 16] 平方 np.exp(arr) # 指数 e^x np.log(arr) # 自然对数(0→-inf,负数→nan) np.log2(arr) # 以 2 为底 np.log10(arr) # 以 10 为底 np.sin(arr) # 三角:sin / cos / tan np.arcsin(arr) # 反三角 np.ceil(arr) # 向上取整 np.floor(arr) # 向下取整 np.rint(arr) # 四舍五入 np.sign(arr) # 符号:-1 / 0 / 1 np.isfinite(arr) # 是否有限(识别 inf/nan) np.round(arr, 2) # 四舍五入到 2 位小数 常用二元 ufunc(两个数组 → 一个数组) a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) np.add(a, b) # [5 7 9] 加法(等价 a + b) np.subtract(a, b) # [-3 -3 -3] 减法 np.multiply(a, b) # [4 10 18] 乘法 np.divide(a, b) # [0.25 0.4 0.5] 除法 np.power(a, b) # [1 32 729] 乘方 np.maximum(a, b) # [4 5 6] 逐元素取较大 np.minimum(a, b) # [1 2 3] 逐元素取较小 np.mod(a, b) # 取余 np.hypot(a, b) # sqrt(a²+b²) 勾股 💡 很多符号运算(+、*、>)底层就是在调用这些 ufunc(np.add、np.multiply、np.greater)——运算符只是语法糖。 ...

2026-08-30 · OC