Python-数组切片

Python-数组切片

在SegmentFault上遇到一个问题,发现自己也不懂,找了资料弄懂了,翻译一下,加深印象。

本文翻译自usc.edu slicing-arrays

基于维度的切片

Python的切片可以被用于数组,它基于每一个维度。例如有一个3x3的数组:

>>> a = reshape(arange(9), (3,3))
>>> print(a)
[[0 1 2]
 [3 4 5]
 [6 7 8]]
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

如果只使用[:] 表示一个从数组开始到结束的切片:

>>> print(a[:,:]) # 基于每一个维度,逗号前面是一个维度,后面是一个
[[0 1 2]
 [3 4 5]
 [6 7 8]]
  
  
  • 1
  • 2
  • 3
  • 4

也就是说,没有任何参数的切片[:] 和列表(list)的切片是一样的,可以理解为“取所有的索引”。但是数组切片和列表切片有一个重大的区别(见下文)。

既然是基于维度,那么我们可以这样取第二维的第二个元素:

>>> print(a[:,1])
[1 4 7]
  
  
  • 1
  • 2

Note that what was a “column” vector is now a “row” vector any “integer
slice” (as in the 1 in the example above) results in a returned array with
rank one less than the input array.

任何一个整数切分,即上面例子里面的1 ,都会导致取得的切片比原来的数组少一个维度

译者注:: 代表取遍第一维,1 相当于数组下标,即相当于做了平常常用的取数组元素second[1] 操作,所以就少了一个维度

再来几个例子

>>> print(a[:,0]) # 取所有第一维,第二维的第一个元素,即第一列
[0 3 6]
>>> print(a[:,0:2]) # 第一维的所有,第二维的[0,2)区间
[[0 1]
 [3 4]
 [6 7]]
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

数组切片和列表切片的区别

列表切片(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]
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果切片没有表面所有维度,没有表明的即表示取所有 操作:

A[1] == A[1,:] == A[1,:,:] # A是一个3维数组
  
  
  • 1

间隔(步长)

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]
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

切片的起始和终止索引的处理和列表是一样的,如上述代码的print(a[2::-1, 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])
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

注意到上面例子里面的特点了吗?

复制是从左向右的 即所有右边的值总是比左边的值晚赋值。

为了避免这种奇怪的结果(可能是你不想要的),你可以使用上面讲到的copy 方法。

猜你喜欢

转载自blog.csdn.net/qq_32727339/article/details/82822736