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

如何用多变量索引2的幂次方阵的行/列轴以提取子矩阵?

用Numpy高效实现幂次方阵的二元组索引

对于2的幂次方阵的分块/二元组索引需求,Numpy的维度重塑(reshape)+ 多维度索引是最高效的方案,完全不需要手动映射索引,而且操作都是矢量化的,性能拉满。

核心思路

把原方阵的行/列维度拆分成「块索引」+「块内索引」的组合,通过reshape将矩阵转换成多维度数组,之后直接用你想要的二元组(或多元组)作为索引访问即可。

4x4矩阵示例(对应你的需求)

先把普通列表转成Numpy数组,再按块大小重塑维度:

import numpy as np

# 初始化4x4矩阵
M = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
    [13, 14, 15, 16]
])

# 重塑为(块行索引r1, 块内行索引r2, 块列索引c1, 块内列索引c2)
# 这里块大小是2x2,所以维度是(2,2,2,2)
M_blocked = M.reshape(2, 2, 2, 2)

接下来直接实现你要的索引效果:

  • 单个元素访问:M[(0,0),(0,0)] → 对应M_blocked[0, 0, 0, 0]
    print(M_blocked[0, 0, 0, 0])  # 输出:1
    
  • 单个元素访问:M[(1,0),(1,1)] → 对应M_blocked[1, 0, 1, 1]
    print(M_blocked[1, 0, 1, 1])  # 输出:12
    
  • 整行访问:M[(0,1),] → 取r1=0、r2=1的行,展平为一维
    print(M_blocked[0, 1, :, :].flatten())  # 输出:[5 6 7 8]
    
  • 子矩阵访问:M[(0,),(0,)] → 取r1=0的所有块内行、c1=0的所有块内列
    print(M_blocked[0, :, 0, :])
    # 输出:
    # [[1 2]
    #  [5 6]]
    

8x8矩阵示例(自定义块大小)

按你的要求,把8x8矩阵分成2个4x4子块(r1∈[0,1],r2∈[0-3]),只需调整reshape的参数:

# 初始化8x8矩阵
M_8x8 = np.arange(64).reshape(8,8)

# 重塑为(块行r1, 块内行r2, 块列c1, 块内列c2),块大小4x4
M_8x8_blocked = M_8x8.reshape(2, 4, 2, 4)

# 取r1=1、r2=2的整行(对应原矩阵第6行)
print(M_8x8_blocked[1, 2, :, :].flatten())  # 输出:[48 49 50 51 52 53 54 55]

# 取左上角4x4子矩阵
print(M_8x8_blocked[0, :, 0, :])
# 输出原矩阵0-3行、0-3列的所有元素

为什么这个方法高效?

Numpy的reshape是视图操作,不会复制原矩阵的数据,只是改变了数据的访问方式,所以几乎没有额外开销,比手动计算映射索引快得多,尤其适合大矩阵场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:57:20