Python中如何用列表切片二维矩阵?为何指定索引结果形状非(3,3)?
为什么numpy列表索引得到一维数组,以及如何获取二维子矩阵
首先得搞清楚numpy里**花式索引(fancy indexing)**的规则,这是你遇到问题的核心原因:
当你写a[[1,2,3],[1,2,3]]时,numpy会把两个列表里的元素一一配对,取的是矩阵中(1,1)、(2,2)、(3,3)这三个单独的元素,所以最终返回的是一个包含这三个元素的一维数组,形状自然是(3,)。
而切片a[1:4,1:4]是完全不同的逻辑:它选取的是行索引从1到3(左闭右开)的所有行,以及列索引从1到3的所有列,相当于取了一个3x3的子矩阵,所以形状是(3,3)。
如果你想通过列表索引实现类似a[[1,8,12],[34,45,50]]得到(3,3)矩阵的需求,也就是取这三行和这三列的所有交叉元素,有几种简单的方法:
方法1:使用np.ix_()函数(最推荐)
np.ix_()的作用就是把一维的行、列索引转换成可以广播成二维的索引结构,让numpy理解你要取的是行和列的所有组合:
import numpy as np a = np.random.rand(100, 100) # 模拟你的100x100矩阵 result = a[np.ix_([1,8,12], [34,45,50])] print(result.shape) # 输出 (3, 3)
方法2:利用广播机制,把行索引改成二维数组
把行索引变成一个列向量(形状(3,1)),这样numpy会自动把它和列索引(形状(3,))广播成(3,3)的索引矩阵,从而取到所有交叉元素:
result = a[[[1],[8],[12]], [34,45,50]] print(result.shape) # 输出 (3, 3)
方法3:分步索引(先取行再取列)
先提取目标行的所有列,再从这个子矩阵里提取目标列,逻辑更直观:
selected_rows = a[[1,8,12], :] result = selected_rows[:, [34,45,50]] print(result.shape) # 输出 (3, 3)
这三种方法都能达到你想要的效果,其中np.ix_()是最简洁且可读性最高的方式,尤其适合处理更长的索引列表。
内容的提问来源于stack exchange,提问作者A.Razavi
相关产品推荐
相关产品推荐

