如何高效按指定索引拆分numpy数组为多个目标子数组
numpy按非连续索引拆分二维数组的高效实现
你需要的非连续行列子矩阵提取可以直接用numpy的花式索引完成,底层为C实现,哪怕是24×24甚至更大规模的数组都没有性能开销,不需要写循环。
实现步骤
- 提前定义好两类索引集合
把需要提取的行、列序号提前存为列表或者numpy数组即可,后续换不同规模的数组只需要修改这里的索引值:
import numpy as np # 按你的示例定义索引,24*24数组仅需修改这两个列表的内容 f_idx = [2, 3, 4, 5, 7] # Kff对应的行、列索引 p_idx = [0, 1, 6] # Kpp、Kpf对应的行索引,可根据实际规则调整
- 调用
np.ix_生成索引网格,直接提取三个子数组
注意不要直接写K[f_idx, f_idx],这种写法只会提取对角位置的元素,np.ix_会将一维索引转换为可广播的网格结构,正确提取所有行列交叉位置的元素:
# 提取三个目标子数组 Kff = K[np.ix_(f_idx, f_idx)] # 行、列均取f_idx Kpp = K[np.ix_(p_idx, p_idx)] # 行、列均取p_idx Kpf = K[np.ix_(p_idx, f_idx)] # 行取p_idx,列取f_idx
效果验证
你可以用小尺寸测试数组验证提取结果是否符合预期:
# 生成8*8测试数组,元素值=行号*10+列号,方便核对 K = np.array([[i*10 + j for j in range(8)] for i in range(8)]) f_idx = [2,3,4,5,7] Kff = K[np.ix_(f_idx, f_idx)] print(Kff)
输出结果就是行索引2、3、4、5、7和列索引2、3、4、5、7交叉的所有元素,完全匹配你的需求。
提示:numpy默认索引从0开始,和你描述的索引规则完全一致,不需要额外做序号转换。
内容的提问来源于stack exchange,提问作者livelysteak
相关产品推荐
相关产品推荐

