python的切片操作十分简洁,但是自己遇到的问题是在切片操作发现省略号,经过查询原来是高维数组切片操作。现在进行一下记录。
首先,第一个问题是python中的列表list和numpy中的array的关系。二者是不同的。虽然都可以构建数组进行切片操作,但是二者是两回事,可以互相转换。
list是python内置的集合类型,与tuple元组、dictionary字典同属三大集合类型。list可以是字符也可以是数字,可以是任意对象混合,当全是数值时,可以当做数组使用。但是list保存的是对象的指针,当保存一个list时,不仅要保存对象还要保存对象指针,显然比较浪费资源。
list对于list存在着添加元素append、删除元素remove等操作,但是array没有。最大不同,无法对整个list的数值进行操作,如两个list相加只是单纯的叠加,并不是数值上的相加;或者list乘以常数时,是多次的叠加。
>>> a = [1,2,3]
>>> type(a)
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> a + a
[1, 2, 3, 4, 1, 2, 3, 4]
>>> a * 3
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
array是numpy包中的类型。注意array与list不同,它要求元素类型为同一类型。array类型可以对数值进行相应的操作,所以利用array构建数组会更好一点。
>>> b = np.array([1,2,3])
>>> b + b
array([2, 4, 6])
>>> b * 3
array([3, 6, 9])
list类型和array类型可以相互转换:
>>> c = np.array(a) # 转换为array类型
>>> type(c)
>>> d = c.tolist() # 转换为list类型
>>> type(d)
接下来是主题,一维数组切片操作对于list和array来说都一样,但是到二维以及多维,嵌套的list切片操作就变得比较鸡肋,只能横向切片,所以多维数组切片指的都是array类型。
一维数组切片:
索引都是从0开始的,对于一维数组来说存在三个参数,[起始位置:终点位置:步长]。其中-1代表最后一个位置。加冒号代表后面的都包括,不加代表取单独一个元素。
>>> a = [1, 2, 3, 4, 6, 7]
>>> a[1:]
[2, 3, 4, 6, 7]
>>> a[-3:]
[4, 6, 7]
>>> a[1::2]
[2, 4, 7]
二维数组切片:
这里开始单指array类型。 其实操作也很简单,参数由两部分组成,分别代指二维数组的两个下标,个人理解是第一个是行,第二个是列。经过实验发现步长参数还是可以用的,也就是为[起始位置:终点位置:步长,起始位置:终点位置:步长]
>>> b = np.array([[1, 2, 3],[4, 5, 6]])
# 取一行
>>> b[0]
array([1, 2, 3])
# 取一列
>>> b[:,1]
array([2, 5])
# 取两列
>>> b[:,-2:]
array([[2, 3],
[5, 6]])
# 采用步长,取两列
>>> b[:,::2]
array([[1, 3],
[4, 6]])
# 取一个值
>>> b[0,1]
2
>>> b[0][1]
2
自己的理解就是,逗号之前的索引部分代表选取几行,逗号之后的索引代表选取几列。
多维数组切片(三维及以上)
省略号的出现就是在多维数组切片时出现了,省略号代表省略了多个冒号。
多维的切片往往令人不好在空间上想象,但是,以三维为例,每一个部分其实依旧对应每一维的下标。对于我而言三维数据,习惯第一维想成各个面,然后第二维是每面中的行数,第三维是每面中的列数。
同样在多维数组切片步长还是可以用的,多维就是比二维多几个维度,当出现多个冒号时可以用省略号替代。
>>> c = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
>>> c
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
# 取第一个面
>>> c[0]
array([[1, 2, 3],
[4, 5, 6]])
# 取两个面中的第一行
>>> c[:,0]
array([[1, 2, 3],
[7, 8, 9]])
# 取两个面中的第一列,使用省略号
>>> c[...,0]
array([[ 1, 4],
[ 7, 10]])
>>> c[:,:,0]
array([[ 1, 4],
[ 7, 10]])
# 取两个面中的前两列
>>> c[...,:2]
array([[[ 1, 2],
[ 4, 5]],
[[ 7, 8],
[10, 11]]])
# 使用步长取两面中的间隔两列
>>> c[...,::2]
array([[[ 1, 3],
[ 4, 6]],
[[ 7, 9],
[10, 12]]])
三维数组切片还可以根据空间想象来切片,但是更高维的话就依次根据对应的维度按照需求进行切片就行。