numpy中沿3D矩阵所有平面切片的高效实现方法
Numpy 3D数组批量平面切片实现
你逐行手动索引+vstack拼接的写法冗余度很高,数组尺寸调整时还得逐行改代码,完全可以通过numpy内置的轴变换、对角提取接口批量生成所有切片,全程走numpy底层C实现,比手动拼接效率高很多,而且代码可复用性强。
正交切片(共9片,对应原代码a~i)
你要的三个方向各3片切片,本质是固定某一个轴的索引取截面,只需要通过轴置换把要固定的轴换到第0位,直接沿第0轴拆分就能得到所有对应切片,不需要逐行索引:
- 左右方向垂直切片(a/b/c):用
np.moveaxis(r, 2, 0)把原数组最后一个轴换到第0位,拆分后得到的3个2D数组和你手动拼的a、b、c完全一致 - 水平切片(d/e/f):用
np.moveaxis(r, 1, 0)把原数组第二个轴换到第0位,拆分后得到的3个2D数组对应d、e、f - 前后方向垂直切片(g/h/i):直接沿原数组第0轴拆分即可,对应g、h、i
以上轴变换操作在新版numpy中返回原数组的视图,没有冗余内存拷贝,处理大体积数组时性能优势明显。
对角切片(共4片,对应原代码j~m)
不需要手动逐点索引拼对角,直接用np.diagonal接口可以批量提取指定两个轴平面的对角,反对角只需要把对应轴反转后再提取即可:
- 正对角j:对应0轴和2轴平面的主对角,直接调用
np.diagonal(r, offset=0, axis1=0, axis2=2).T即可 - 反对角k:先把最后一个轴倒序,再提取0轴和2轴平面的主对角,即
np.diagonal(r[..., ::-1], offset=0, axis1=0, axis2=2).T - 反对角l:先把第二个轴倒序,再提取0轴和1轴平面的主对角,即
np.diagonal(r[:, ::-1, :], offset=0, axis1=0, axis2=1) - 正对角m:对应0轴和1轴平面的主对角,直接调用
np.diagonal(r, offset=0, axis1=0, axis2=1)即可
完整简化代码
import numpy as np r = np.array([ [[1,2,3], [4,5,6], [2,8,9]], [[10,11,12], [13,14,15], [2,17,18]], [[19,20,21], [22,23,24], [25,26,27]], ]) # 批量生成9个正交切片 orth_slices = list(np.moveaxis(r, 2, 0)) + list(np.moveaxis(r, 1, 0)) + list(r) # 批量生成4个对角切片 diag_slices = [ np.diagonal(r, 0, 0, 2).T, np.diagonal(r[..., ::-1], 0, 0, 2).T, np.diagonal(r[:, ::-1, :], 0, 0, 1), np.diagonal(r, 0, 0, 1) ] # 合并得到最终13个切片的数组,和手动拼接结果完全一致 al = np.array(orth_slices + diag_slices)
运行这段代码得到的al和你手动逐片拼接的输出数值完全相同,后续如果处理N×N×N尺寸的3D数组,这段代码不需要任何修改就能直接使用。
内容的提问来源于stack exchange,提问作者user2315546
相关产品推荐
相关产品推荐

