引言

数组索引是指使用方括号([])来索引数组值。我们最为熟悉的索引方式就是单个元素索引。此外,本文还将介绍数组切片的索引方式,以及索引数组、布尔索引数组和结构索引工具等内容。

1. 单个元素索引

注意:索引的起始位置为0
当数组为一维数组时:

>>> x = np.arange(10)	# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> x[2]
2
>>> x[-2]
8

当数组为多维数组时:
numpy数组也支持多维数组的多维索引。

>>> x.shape = (2,5) # 现在 x 是一个二维数组
# array([[0, 1, 2, 3, 4],
#       [5, 6, 7, 8, 9]])
>>> x[1,3]	# 数组 x 的 第1行 第3列 对应的元素
8
>>> x[1,-1]	# 数组 x 的 第1行 最后1列 对应的元素
9
>>> x[0]	#索引索引比维度少的多维数组,则会获得一个子维数组
array([0, 1, 2, 3, 4])

2. 数组切片

与列表和元组一样,数组也可以进行切片,进而索引元素。下面给出一个例子:

>>> x = np.arange(10)
>>> x[2:5]
array([2, 3, 4])
>>> x[:-7]
array([0, 1, 2])
>>> x[1:7:2]
array([1, 3, 5])
>>> y = np.arange(35).reshape(5,7)
>>> y[1:5:2,::3]
array([[ 7, 10, 13],
       [21, 24, 27]])

[ ] 中第一个 :前为 索引的起始值,第一个 :后为 索引的结束值,第二个 :后为 索引的步长。以 x[1:7:2] 为例,进行分析:索引起始位置为1,结束位置为7(不包含索引为7对应的元素),步长为2,因此 x[1:7:2] 的索引结果为 [1, 3, 5] 。
以 x[2:5] 为例,进行分析:索引起始位置为2,结束位置为5(不包含索引为7对应的元素),步长省略则默认为1,因此 x[2:5] 的索引结果为 [2, 3, 4] 。
以 y[1:5:2,::3] 为例,进行分析:y 是多维数组,逗号前是数组第一维的索引,逗号后是数组第二维的索引,数组各维的索引方式和一维数组的索引方式相同。其中,1:5:2 代表起始索引为 1,结束索引为5(不包含索引为5对应的元素),步长为2。因此 y[1:5:2] 的索引结果为 数组 y 的第二行 和 第四行。即

>>> y[1:5:2]
array([[ 7,  8,  9, 10, 11, 12, 13],
       [21, 22, 23, 24, 25, 26, 27]])

[::3] 代表第二维索引的步长为3,不对起始和结束索引位置做限制。即取 y[1:5:2] 的第1列、第4列、第7列。因此

>>> y[1:5:2,::3]
array([[ 7, 10, 13],
       [21, 24, 27]])

3. 索引数组

numpy 数组也支持数组索引数组,即 [ ] 中可以是一个数组。下面举个例子进行说明:

>>> x = np.arange(10,1,-1)	# 此次 -1 指步长为-1,即倒序
>>> x
array([10,  9,  8,  7,  6,  5,  4,  3,  2])
>>> x[np.array([3, 3, 1, 8])]	# 对数组 x 的第4、4、2、9个元素进行索引
array([7, 7, 9, 2])
>>> x[np.array([3,3,-3,8])]
array([7, 7, 4, 2])

x 的 [ ] 中为np.array([3, 3, 1, 8]),即值3,3,1和8组成的索引数组。一般来说,使用索引数组时返回的是与索引数组具有相同形状的数组。下面给出一个使用多维索引数组的例子:

>>> x[np.array([[1,1],[2,3]])]
array([[9, 9],
       [8, 7]])

4. 布尔索引数组

用作索引的布尔数组的形状必须与要索引的数组的初始尺寸相同。布尔索引结果是一个一维数组,其中包含索引数组中与布尔数组中所有真实元素对应的所有元素。下面给出一个例子来具体分析:

>>> y = np.arange(35).reshape(5,7)
>>> b = y>20
>>> b
array([[False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False],
       [ True,  True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True]], dtype=bool)
>>> y[b]
array([21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34])

数组 y 是一个 5 行 7 列的数组, b 是一个布尔数组,y > 20 对应的索引位置为 True,其他为 False。索引数组 b 用作 数组 y 的索引,返回一个一维数组。其中数组元素为索引数组 b 中为 True 的索引对应数组 y 的元素。

5. 结构索引工具

np.newaxis 是 深度学习中常用的 numpy 函数。在数组索引中可以使用np.newaxis对象来添加大小为1的新维度。

>>> y
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, 32, 33, 34]])
>>> y.shape
(5, 7)
>>> y[:,np.newaxis,:]
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, 32, 33, 34]]])
>>> y[:,np.newaxis,:].shape
(5, 1, 7)
>>> y[np.newaxis,:,:]
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, 32, 33, 34]]])
>>> y[np.newaxis,:,:].shape
(1, 5, 7)
>>> y[:,:,np.newaxis]
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],
        [32],
        [33],
        [34]]])
>>> y[:,:,np.newaxis].shape
(5, 7, 1)

如上所示,数组中没有新元素,只是增加了维度。但是这有什么用呢?
这可以方便地组合两个数组,否则将需要显式重新整形操作。例如:

>>> x = np.arange(5)
>>> x
array([0, 1, 2, 3, 4])
>>> x[:,np.newaxis]
array([[0],
       [1],
       [2],
       [3],
       [4]])
>>> x[np.newaxis,:]
array([[0, 1, 2, 3, 4]])
>>> x[:,np.newaxis] + x[np.newaxis,:]
array([[0, 1, 2, 3, 4],
       [1, 2, 3, 4, 5],
       [2, 3, 4, 5, 6],
       [3, 4, 5, 6, 7],
       [4, 5, 6, 7, 8]])

参考文献

numpy 中文文档

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐