You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NumPy中从p*q大矩阵提取m*n子矩阵?(数独场景示例)

提取9×9矩阵中所有3×3子矩阵的NumPy优化方法

当然有更直接高效的实现方式!你的嵌套np.split/np.hsplit做法是可行的,但NumPy提供了更简洁的数组操作方法,不用写循环就能一次性提取所有3×3子矩阵。下面介绍两种常用的优化方案:

方法1:利用数组重塑(reshape)+ 轴交换(swapaxes)

这是最经典的无循环实现方式,核心是通过重塑数组维度来直接拆分出所有3×3块:

import numpy as np

grid = np.array([
    [5,3,4,6,7,8,9,1,2],
    [6,7,2,1,9,5,3,4,8],
    [1,9,8,3,3,2,5,6,7],
    [8,5,9,7,6,1,4,2,3],
    [4,2,6,8,5,3,7,9,1],
    [7,1,3,9,2,4,8,5,6],
    [9,6,1,5,3,7,2,8,4],
    [2,8,7,4,1,9,6,3,5],
    [3,4,5,2,8,6,1,7,9]
])

# 一次性提取所有3×3子矩阵
blocks = grid.reshape(3, 3, 3, 3).swapaxes(1, 2).reshape(-1, 3, 3)

# 打印结果
for block in blocks:
    print(block)
    print("---")

原理说明:

  1. grid.reshape(3, 3, 3, 3):把原9×9矩阵拆分为3个行块(每个行块3行)×3个列块(每个列块3列),维度变为(行块数, 行块内行数, 列块数, 列块内列数);
  2. swapaxes(1, 2):调整轴的顺序,将维度转换为(行块数, 列块数, 行块内行数, 列块内列数),让每个行块对应的列块可以直接组合成完整的3×3子矩阵;
  3. reshape(-1, 3, 3):将所有子矩阵展平为一个数组,其中每个元素都是3×3的子矩阵(最终得到9个3×3块)。

方法2:使用滑动窗口视图(sliding_window_view)

如果你使用的是NumPy 1.20及以上版本,可以用sliding_window_view来更直观地提取非重叠窗口:

from numpy.lib.stride_tricks import sliding_window_view

# 生成所有滑动窗口,然后按步长3取非重叠的3×3块
blocks = sliding_window_view(grid, window_shape=(3, 3))[::3, ::3].reshape(-1, 3, 3)

# 打印结果
for block in blocks:
    print(block)
    print("---")

原理说明:

  1. sliding_window_view(grid, window_shape=(3,3)):生成所有可能的3×3滑动窗口,维度为(7,7,3,3)(因为滑动步长默认是1);
  2. [::3, ::3]:每隔3个窗口取一个,筛选出所有非重叠的3×3块,此时维度为(3,3,3,3);
  3. reshape(-1, 3, 3):同样将所有子矩阵展平为9个3×3块的数组。

这两种方法都能得到和你原来代码完全一致的结果,而且避免了循环开销,代码更简洁,处理大矩阵时效率优势更明显。

内容的提问来源于stack exchange,提问作者Thalish Sajeed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:28:07