Numpy的基础索引与切片

一、基础索引

Numpy数组索引是一个大话题,有很多方式可以让你选中数据的子集或某个单位元素。一维数组比较简单,看起来和Python的列表类似:

import numpy as np
arr = np.arange(10)

arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

arr[5]
5

arr[5:8]
array([5, 6, 7])

arr[5:8] = 12

arr
array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])

(1)、一维数组

如你所见,如果你传入了一个数值给数组的切片,例如 arr[5:8] = 12,数值被传递给了整个切片。区别于Python的内建列表,数组的切片是原数组的视图。这意味着数据并不是被复制了,任何对于视图的修改都会反映到原数组上。

比如:

arr_1 = arr[5:8]

arr_1
array([12, 12, 12])

当我改变arr_1时,变化也会体现在原数组上:

arr_1[1] =123

arr
array([  0,   1,   2,   3,   4,  12, 123,  12,   8,   9])

不写切片值[ :]将会引用数组的所有值:

arr_1[:] = 64

arr
array([ 0,  1,  2,  3,  4, 64, 64, 64,  8,  9])

如果你还是想要一份数组切片的拷贝而不是一份视图的话,你就必须显式地复制这个数组,例如arr[5:8].copy()

(2)、二维数组

对更高维度的数组,你会有更多选择。在一个二维数组中,每个索引值对应的元素不再是一个值,而是一个一维数组:

arr_2 = np.array([[1,2,3],[4,5,6],[7,8,9]])

arr_2[2]
array([7, 8, 9])

因此,单个元素可以通过递归的方式获得。但是要多写一点代码,你可以通过传递一个索引的逗号分隔列表去选择单个元素,以下两种方式效果一样:

arr_2[0][2]
3

arr_2[0,2]
3

(3)、多维数组

在多维数组中,你可以省略后续索引值,返回的对象将是降低一个维度的数组。因此,在一个2 * 2 * 3的数组arr_3中:

arr_3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])

arr_3
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])

arr_3[ 0 ]是一个2*3的数组:

arr_3[0]
array([[1, 2, 3],
       [4, 5, 6]])

标量和数组都可以传递给arr_3[ 0 ]:

old_values = arr_3[0].copy()
arr_3[0] = 42

arr_3
array([[[42, 42, 42],
        [42, 42, 42]],

       [[ 7,  8,  9],
        [10, 11, 12]]])

old_values 
array([[1, 2, 3],
       [4, 5, 6]])

arr_3[0] = old_values 

arr_3
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])

类似的,arr_3[ 1 ,0]返回的是一个一维数组:

arr_3[1,0]
array([7, 8, 9])

当然上面的表达式也可以分解为下面两步:

x = arr_3[1]

x
array([[ 7,  8,  9],
       [10, 11, 12]])

x[0]
array([7, 8, 9])

需要注意的是,以上的数组子集选择中,返回的数组都是视图

二、切片索引

与Python列表的一维对象类似,数组可以通过类似的语法进行切片:

arr
array([ 0,  1,  2,  3,  4, 64, 64, 64,  8,  9])

arr[1:6]
array([ 1,  2,  3,  4, 64])

在二维数组中,对数组进行切片又略有不同:

arr_2
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

arr_2[:2]
array([[1, 2, 3],
       [4, 5, 6]])

如你所见,数组沿着轴0进行了切片。表达式arr_[ :2]的含义为选择arr_2的前俩行。

你可以进行多组切片,与多组索引类似:

arr_2[:2,1:]
array([[2, 3],
       [5, 6]])

当你像在上面这个例子中那样切片时,你需要按照原数组的维度进行切片。如果将索引和切片混合,就可以得到低维度的切片。

例如,我可以下载第二行但是只是选择前两列:

arr_2[1,:2]
array([4, 5])

类似的,我也可以选择第三列,但是只是选择前两行:

arr_2[:2,2]
array([3, 6])

当然,需要注意的是,单独一个冒号表示选择整个轴上的数组,因此你可以按照下面的方式在更高维度上进行切片:

arr_2[:,:1]
array([[1],
       [4],
       [7]])

当然对切片表达式赋值时,整个切片都会出现赋值:

arr_2[:2,1:] = 0

arr_2
array([[1, 0, 0],
       [4, 0, 0],
       [7, 8, 9]])

数组的切片方式千变万化,对于新手来说只要能找到自己想要的数据就是最合适的。

猜你喜欢

转载自blog.csdn.net/qq_41205111/article/details/86658105