基于维度的切片
Python的切片可以被用于数组,它基于每一个维度。例如有一个3x3的数组:
>>> a = reshape(arange(9), (3,3))>>> print(a)
[[0 1 2]
[3 4 5]
[6 7 8]]
如果只使用[:] 表示一个从数组开始到结束的切片:
>>> print(a[:,:]) # 基于每一个维度,逗号前面是一个维度,后面是一个[[0 1 2]
[3 4 5]
[6 7 8]]
既然是基于维度,那么我们可以这样取第二维的第二个元素:
>>> print(a[:,1])
[147]
取遍第一维,1 相当于数组下标,即相当于做了平常常用的取数组元素second[1] 操作,所以就少了一个维度
>>> print(a[:,0]) # 取所有第一维,第二维的第一个元素,即第一列
[0 3 6]
>>> print(a[:,0:2]) # 第一维的所有,第二维的[0,2)区间
[[0 1]
[3 4]
[6 7]]
数组切片和列表切片的区别
列表切片(slice of lists) 是原有列表的所取部分的复制
数组切片(slice of arrays) 只是提供一个所取数组元素的访问入口,如果想取得原有数组的copy,可以使用copy方法,翻译太挫上例子:
>>> a = arange(20)
>>> b = a[3:8]
>>> c = a[3:8].copy()
>>> a[5] = -99
>>> print(b) # 修改a,a的切片b也变了,说明b并没有copy原数组
[ 3 4 -99 6 7]
>>> print(c) # c不会变,因为它是copy原来数组的
[3 4 5 6 7]
如果切片没有表面所有维度,没有表明的即表示取所有 操作:
A[1] == A[1,:] == A[1,:,:]# A是一个3维数组
间隔(步长)
python列表中取逆序列表可以这样somelist[::-1] 用到了切片的第三个参数step 即步长,当然数组切片也是可以的。不过Python 2.3之前的版本不支持此操作。
>>> a = reshape(arange(9),(3,3))
>>> print(a)[[0 1 2]
[3 4 5]
[6 7 8]]>>> print(a[:, 0])
[0 3 6]
>>> print(a[0:3, 0])
[0 3 6]
>>> print(a[2::-1, 0]) #等效于print(a[::-1, 0])
[6 3 0]
关键字...
还有一种数组切片的方法:使用关键字...
这个关键字表示:我想用多少: 取决于数组的维度有多少,我明确指定的索引将会在所有要取的索引的末尾(翻译得我都怀疑自己能不能看懂)。上例子:
三维数组 A[...,0] –> A[:,:,0]a
四维 B[...,0] –> B[:,:,:,0]
五维 C[...,0,...] –>C[:,:,:,0,:]
注意这个五维的C有两个... ,我指明了一个0 ,它应该尽量靠后,所以就有了上面的结果
切片赋值
想要将一个数组切片的值整体赋给另一个同样大小的切片,这个操作很容易,但是如果这两个切片是同一个数组的,并且它们是重叠的,结果可能会让你惊讶
>>> n = arange(36)>>> n[11:18] = n[7:14]# 将[7,14) 的值赋给[11,18)
array([0,1,2,3,4,5,6,7,8,9,10,7,8,9,10,7,8,9,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35])
注意到上面例子里面的特点了吗?
复制是从左向右的 即所有右边的值总是比左边的值晚赋值。
为了避免这种奇怪的结果(可能是你不想要的),你可以使用上面讲到的copy 方法。