arr[[3, 5, 0, 6]]会索引源数组的第三行、第五行、第零行、第六行,然后组成新的视图返回,而arr[[3, -3, -1]]则会索引第三行、倒数第三行和倒数第一行
我们生成了一个8×4数组,然后传入两个索引数组[1, 5, 7, 2]、 [0, 3, 1, 2],然后我们得到一个一维的数组
>>> arr = np.arange(32).reshape((8, 4))
>>> arr
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27],
[28, 29, 30, 31]])
>>> arr[[1, 5, 7, 2], [0, 3, 1, 2]]
array([ 4, 23, 29, 10])
下面我们分析一下上面的代码究竟发生了什么,第一个索引数组[1, 5, 7, 2],我们获取第一行、第五行、第七行和第二行,然后我们将根据第二个索引数组 [0, 3, 1, 2],获取第一行的第零列、第五行的三列……以此类推,最后,我们获得了一个一维的数组
当然,在有些情况下,我们希望按照不同的顺序获取源数组不同的行,并且还要在获取后,改动原来的列顺序,于是我们可以这样做:
>>> arr[[1, 5, 7, 2]]
array([[ 4, 5, 6, 7],
[20, 21, 22, 23],
[28, 29, 30, 31],
[ 8, 9, 10, 11]])
>>> arr[[1, 5, 7, 2]][:, [2, 1, 3, 0]]
array([[ 6, 5, 7, 4],
[22, 21, 23, 20],
[30, 29, 31, 28],
[10, 9, 11, 8]])
>>> arr[np.ix_([1, 5, 7, 2], [2, 1, 3, 0])]
array([[ 6, 5, 7, 4],
[22, 21, 23, 20],
[30, 29, 31, 28],
[10, 9, 11, 8]])
如上,我们既可以用arr[[1, 5, 7, 2]][:, [2, 1, 3, 0]]这样的方式获取获取不同的行,再改变其中的列顺序,同时也可以用np.ix_函数达到一样的目的,不过需要注意的一点是,花式索引跟分片不一样,它总是将数据复制到新的数组中:
>>> arr1 = arr[np.ix_([1, 5, 7, 2], [2, 1, 3, 0])]
>>> arr1
array([[ 6, 5, 7, 4],
[22, 21, 23, 20],
[30, 29, 31, 28],
[10, 9, 11, 8]])
>>> arr1[1] = 66
>>> arr1
array([[ 6, 5, 7, 4],
[66, 66, 66, 66],
[30, 29, 31, 28],
[10, 9, 11, 8]])
>>> arr
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27],
[28, 29, 30, 31]])