使用 numpy.split 时需确保沿指定轴能被等分,否则报错;numpy.array_split 可处理不整除情况,自动将多余元素分配至前面若干块。

用 numpy.split 和 numpy.array_split 切分矩阵时要注意什么
直接切分二维数组最常用的是 numpy.split,但它要求沿指定轴能被等分,否则报 ValueError: array split does not result in an equal division。实际中数据尺寸常不整除,这时得换 numpy.array_split——它会尽量均分,多出来的元素往前几块塞。
比如对 shape 为 (100, 64) 的矩阵按行切 7 块:
import numpy as np X = np.random.rand(100, 64) chunks = np.array_split(X, 7, axis=0) # 得到 7 个子数组,长度分别是 [15, 15, 15, 15, 15, 15, 10]
-
axis=0表示按行切(得到多个小矩阵),axis=1是按列切 -
np.split更快但严格,适合预知尺寸可整除的场景(如 batch size 固定) -
array_split内部用np.arange+np.array拆索引,有轻微开销,但安全
用 numpy.lib.stride_tricks.sliding_window_view 做滑动分块
做卷积、时序窗口或局部统计时,需要重叠分块,sliding_window_view 是 NumPy 1.20+ 的标准方案,比手写循环或 as_strided 安全得多。
例如从长度 100 的向量中取长度为 10、步长为 3 的滑动窗口:
from numpy.lib.stride_tricks import sliding_window_view x = np.arange(100) windows = sliding_window_view(x, window_shape=10)[::3] # shape (30, 10)
- 注意:返回的是视图(view),不是副本,修改会影响原数组;需副本就加
.copy() - 二维滑动(如图像 patch)要传 tuple:
sliding_window_view(img, (8, 8)),结果 shape 是(h-7, w-7, 8, 8) - 旧版本 NumPy 没这个函数,别硬升,可用
skimage.util.view_as_windows替代
手动构造索引分块比调用函数更快?
当分块逻辑复杂(比如按 mask 筛选、非均匀间隔、条件跳过),硬套 split 反而绕路。直接用布尔索引或整数索引更清晰,也更容易控制内存。
例如只取每 5 行中第 2、4 行组成新块:
idx = np.arange(X.shape[0]) mask = (idx % 5 == 1) | (idx % 5 == 3) # 第 2、4 行(0-indexed) subset = X[mask] # 直接得到 (40, 64) 子矩阵
- 避免用
np.where(mask)[0]再索引——多一次计算,X[mask]就够了 - 如果块数很多且每块大小不一,用
np.split(X, indices, axis=0)配合预计算的切分点更稳,比循环 append 快一个数量级 - 注意
indices是“分割位置”,不是“起始索引”,[10, 25]表示切在第 10 行和第 25 行之前
分块后运算如何避免隐式拷贝和广播陷阱
分块本身不慢,慢在后续运算里反复触发拷贝或广播。常见坑是:对 list of arrays 调用 np.stack 或 np.concatenate 前没确认 dtype 一致,或误用 np.sum(chunk, axis=0) 却忘了 chunk 形状可能不统一。
- 确保所有块 dtype 相同,尤其混了
float32和float64时,np.stack会悄悄升到float64,内存翻倍 - 若各块 shape 不同(比如最后一块偏小),不能直接
np.stack,改用np.vstack或np.concatenate(它们允许首维不同) - 批量矩阵乘法别写
[A @ b for A, b in zip(chunks_A, chunks_b)],用np.einsum('nij,nj->ni', chunks_A, chunks_b)或np.matmul批量算,快 3–5 倍
分块的核心不是“怎么切”,而是“切完怎么不掉进内存和类型陷阱”。哪怕只多一个 .astype(np.float32) 或少一次 .copy(),千次迭代下来就是秒级差异。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











