- 前言
- 数组索引
- 索引获得单个元素
- 索引获得单个数组
- list索引
- 数组切片
- :索引切片
- 多维切片
- 索引+切片
- list索引+切片
- ...的作用
本篇记录numpy数组的索引和切片方法。
数组索引需要获取numpy数组中的元素,可以采用[index]
索引的方法,其中index
是每一维度的索引,下标从0开始,到n-1结束(类似C++数组索引)。
当索引的维度与数组维度相同时,索引获得的是单个元素的值:
import numpy as np
a = np.array([[1, 2], [3, 4]])
print(a[0, 1]) # 2
print(a[1, 0]) # 3
另外,索引中的-1
表示最后一个元素,-2, -3
依此类推:
a[-1, -1] # 4
a[-2, -2] # 1
索引获得单个数组
当索引的维度小于数组维度时,索引获得的是一个低维数组:
import numpy as np
a = np.array([[1, 2], [3, 4]])
print(a[1]) # array([1, 2])
print(a[0]) # array([3, 4])
实际上,获得的低维数组在高维的角度下,其实就是数组的“元素”。
list索引假设一维numpy数组a.shape=(4,)
,现在我想同时获得第一和第三个元素,可以在索引中使用list:
import numpy as np
a = np.random.randn(4)
a[[0, 2]] # np.ndarray, shape=(2,)
a[0, 2] # error!
这里需要分清,在[]
索引中,使用list和非list的区别:正如上面的示例中,a[[0, 2]]
的意思是提取第一维的第1和第3个元素(可以只有一维),得到的结果是一个新的一维数组;而a[0, 2]
则表示提取第一维的第一个、第二维的第三个元素(必须有两维以上),因此会报错。
简单而言,a[[ind1, ind2]]
是取索引为ind1, ind2
的两个元素作为新数组,而a[ind1, ind2]
是取坐标为(ind1, ind2)
的元素。
此外,使用多维np.ndarray的效果与python list的效果是相同的,但tuple则是与取坐标效果相同:
import numpy as np
a = np.random.randn(4, 4)
a[[0, 2]] # np.ndarray, shape=(2, 4)
a[np.array([0, 2])] # np.ndarray, shape=(2, 4)
a[0, 2] # scalar
a[(0, 2)] # scalar
数组切片
切片操作是numpy的一个特色机制(pytorch, paddle等也应用了这个机制)。数组切片用于一次获取数组中的多个元素,并保持一定的数组结构。
所谓切片,就是在数组中切割出一部分元素出来,通过在索引中使用:
实现。
ind1:ind2
在索引中的意思是获取从索引ind1
(包括)到ind2
(不包括)的元素,也就是左闭右开切片:
import numpy as np
a = np.array([1, 2, 3, 4])
a[1:3] # array([1, 2])
a[:-1] # array([1, 2, 3])
当ind1
为空,表示从该维度第一个元素开始;ind2
为空时,到最后一个元素结束(包含)切片:
a[:] # array([1, 2, 3, 4])
还有ind1:ind2:step
的形式,表示从ind1
开始到ind2
结束,按照step
的步进切片(常用的是[::-1]
,表示从最后一个元素到第一个元素切片):
a[::-1] # array([4, 3, 2, 1])
a[::2] # array([1, 3])
a[1::2] # array([2, 4])
a[1::-1] # array([2, 1])
a[1:2:-1] # array([]), empty array
注意:如果ind1, ind2
都不为空,必须满足step>0
,则ind1 c[:, 1] -------->c[:, :, 1]
# 向右添加':' 向右添加':' 索引长度与数组维度相同,停止添加
c[1, ...] ---------> c[1, :] -------->c[1, :, :]
验证一下:
c[:,:,1]
# array([[ 1, 5, 9],
# [13, 17, 21]])
c[1,:,:]
# array([[12, 13, 14, 15],
# [16, 17, 18, 19],
# [20, 21, 22, 23]])
果然没错。现在是不是就感觉...
非常简单了呢,就是代替连续重复的:
,比较简洁。