使用range/arange函数作为参数,对2维numpy数组进行索引/切片。

3
我在numpy中有一个基本问题。我在使用Python 2.7,numpy-1.9.2和Ubuntu 14.04。
例如,我初始化了一个2d numpy数组,如 a = np.zeros((10,10))
然后我尝试使用range函数作为索引来索引其中一部分,如下所示:a[range(0,5), range(0,5)]。我得到的是一个形状为(5,)的数组。我想要的是2d数组a的前5行和列。
当我执行a[:5,:5]时,它似乎给我一个形状为(5,5)的数组。
有人能解释一下为什么使用range函数指定索引会失败吗?即使我已经使用它工作了近一年,我仍然感到困惑于numpy的索引。
提前感谢您的帮助。

你会期望 a[[0,1,2,3,4],[0,1,2,3,4]] 给你什么结果? - Padraic Cunningham
1个回答

5

使用 range 时,你正在使用如此描述的 整数数组索引:

http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#integer-array-indexing

要获得与 a[0:5,0:5] 相当的内容,你必须利用“广播”。 这里第一个索引是一个列向量。

a[np.arange(0,5)[:,None],range(0,5)]

In [137]: np.arange(0,5)[:,None]
Out[137]: 
array([[0],
       [1],
       [2],
       [3],
       [4]])

我可以提供更详细的信息,但你同样可以阅读该文档。


np.ix_ 是一个实用程序,有助于生成此类索引数组:

In [507]: np.ix_(range(0,5),range(0,5))
Out[507]: 
(array([[0],
        [1],
        [2],
        [3],
        [4]]), array([[0, 1, 2, 3, 4]]))

这个(5,1)数组与一个(1,5)数组广播以产生一个(5,5)的索引数组。

MATLAB和numpy有选择另外的高级索引方法:

在MATLAB/Octave中,a([1,2,3],[1,2,3])索引一个(3,3)的块。在numpy中,a[[1,2,3],[1,2,3]]索引(3,)对角线。

a(sub2ind(size(a),[1,2,3],[1,2,3]))是Octave对角线;a[np.ix_([1,2,3],[1,2,3])]numpy块。


1
谢谢。我将避免使用整数数组或范围。我想知道为什么他们提供了广播整数数组的能力,而不是将它们用作常规切片。 - user3317287
1
有时我们需要从数组中选择块,有时选定的项分散在其中。不需要使用范围来复制您可以用切片轻松完成的内容。 - hpaulj
这太恶心和混乱了。必须有更清洁的方法来实现OP想要做的事情。 - Translunar
我编辑了我的答案来比较numpy和MATLAB的高级索引方法。你可以使块的索引变得容易,也可以使项目的索引变得容易。但用一种符号来保持简单却很难。 - hpaulj
只想补充一下,R使用MATLAB的索引方法。 - daknowles
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接