Numpy:从4D阵列切片3D阵列?

时间:2017-01-19 19:17:29

标签: python python-2.7 python-3.x numpy

假如我有4D numpy维数:10 x 10 x 10 x 10,我想根据我所知的某些索引获得3D子集(例如([1,2],0,[5,6] ],[9,0])。我该如何做到这一点,如果我的指数不是连续的,我该怎么办?比如我的例子?

例如,如果我尝试这样做:

test[0:2, 0, 3:5, 0:2]

我按预期得到一个2 x 2 x 2阵列。但是,如果我尝试明确定义每个维度值,如下所示:

test[[0,1], 0, [3,4], [0,1]]

我改为获得一个2 x 1阵列。我究竟做错了什么?

1 个答案:

答案 0 :(得分:1)

区别在于基本索引和高级索引。使用切片和标量进行索引是“基本的”。当一个或多个索引是列表或数组时,它使用“高级”。 Docs on advanced v basic indexing

有多种方法可以生成所需的索引类型。 np.ix_旨在简化这一过程:

In [80]: np.ix_([0,1], [0], [3,4], [0,1])
Out[80]: 
(array([[[[0]]],


        [[[1]]]]), array([[[[0]]]]), array([[[[3],
          [4]]]]), array([[[[0, 1]]]]))

In [79]: arr[np.ix_([0,1], [0], [3,4], [0,1])].shape
Out[79]: (2, 1, 2, 2)

要通过ix_传递所有索引,我必须将第二个列表作为列表。解决这个问题的方法是仅在3个列表中使用ix_,然后再添加0

In [81]: I,J,K=np.ix_([0,1], [3,4], [0,1])
In [82]: arr[I,i,J,K].shape
Out[82]: (2, 2, 2)
In [83]: I,J,K
Out[83]: 
(array([[[0]],

        [[1]]]), array([[[3],
         [4]]]), array([[[0, 1]]]))

注意索引数组的形状:

In [84]: I.shape
Out[84]: (2, 1, 1)
In [85]: J.shape
Out[85]: (1, 2, 1)
In [86]: K.shape
Out[86]: (1, 1, 2)
他们一起广播成(2,2,2)形状。所以任何以这种方式广播的索引数组都应该有效。您可以使用

制作J
In [87]: J
Out[87]: 
array([[[3],
        [4]]])
In [88]: np.array([3,4])[None,:,None]
Out[88]: 
array([[[3],
        [4]]])