首页 > NumPy 阅读数:42

NumPy数组的索引和切片

在之前教程中介绍了选取数组中的某个特定元素的方法,即在数组名后面加方括号,方括号里面是数组的下标。数组下标就是数组的索引,数组与列表的索引类似,也分为正索引(也称为索引)和负索引两种。数组的索引从 0 开始,自左向右,以 1 为步长逐渐递增。而数组的负索引从右到左标记数组元素,最右边数组元素的负索引为 -1,然后向左边依次类推为 -2、-3 等。

类似于列表,数组通过索引访问数组中的元素,数组的切片也通过索引对数组中的元素进行提取,其中,索引访问提取仅返回数组的一个对应元素,而数组切片则会返回数组中一个区域内所对应的元素。

一维数组的索引与切片

一维数组的操作类似于 Python 中列表(list)类型的操作。首先定义 arr 为一维数组,数组有 n 个元素,则数组中的元素与索引的对应关系如下:

一维数组   arr = [a0, a1, a2, a3, a4,…, an ]
数组索引(下标)     0   1   2   3   4     n

1) 利用数组索引(下标)获取指定元素

获取数组中指定元素的方法如下:

数组名[索引(下标)]

例如,获取数组arr中第 4 个元素 a3 用 arr[3] 即可。

2) 数组的切片

截取数组中某个范围之间元素的方法如下:

数组名[start:end:step]

其中,start 表示截取数组中开始元素的索引(下标),end 表示截取数组中结束元素的索引(下标),但是不包括 end 索引(下标)所指定的元素,step 表示步长。
  • 省略 start 索引(下标),表示从 0 索引(下标)开始;
  • 省略 end 索引(下标),表示截取数据要包括数组最后一个元素;
  • 索引(下标)可以使用负数,-1 表示从数组最后往前数的第一个元素;
  • 数组切片还可以用来修改元素的值。如用 arr[:2]=10,11 可将 arr 数组修改为 arr=[10,11,a2,a3,a4,…,an]。

例如,截取 arr 数组中第 2 个元素至第 5 个元素,包括第 5 个元素,则使用 arr[1:5]。

注意:索引(下标)是从 0 开始,第 2 个元素对应索引(下标)为 1,因为要包括第 5 个元素,end 值选择第 6 个元素索引(下标)。

还有如 arr[:8,2] 表示截取数组元素 [a0,a2,a4,a6],arr[-1] 表示截取数组元素 [an]。

二维数组的索引与切片

二维数组是由行和列组成的,二维数组中的每一行相当于一维数组。二维数组中元素的索引是由该元素所在的行下标和列下标组成的,即由元素的行索引和列索引组成。例如,arr 是二维数组,该二维数组元素用 arr[行索引,列索引] 表示,该二维数组中元素与索引的对应关系如下。
二维数组中元素与索引的对应关系

1) 利用二维数组的行索引和列索引获取指定元素

获取二维数组中指定元素的方法如下:

数组名[行索引,列索引]

例如,获取二维数组中第  2行第 2 列的元素,用 arr[1,1] 即可。

2) 二维数组的切片

截取二维数组中某个区域之间的元素的方法如下:

数组名[rows_start:rows_end:rows_step,cols_start:cols_end:cols_step]

对各个参数的说明:
  • rows_start:rows_end 表示截取数组中元素的行索引范围;
  • cols_start:cols_end 表示截取数组中元素的列索引范围,但不包括 rows_end 行索引和 cols_end 列索引所指定的元素;
  • rows_step 表示行索引的步长,cols_step 表示列索引的步长。

补充说明:
  • 省略 rows_start、cols_start 索引,表示从 0 索引开始;
  • 省略 rows_end、cols_end 索引,表示截取数据要包括行或列最后一个元素;
  • 行索引或列索引可以使用负数,-1 表示从行或列数组最后往前数的第一个元素;
  • 数组切片时,行索引或列索引范围可以使用省略号(…),表示行或列所选择元素的长度与数组的行或列的维度相同;
  • 数组切片还可以用来修改元素的值。

说明:高维数组的索引与切片可参考二维数组的索引和切片方法依次类推。

一维数组和二维数组的元素获取与切片操作示例代码 example1 如下。
# -*- coding: UTF-8 -*-
import numpy as np
#创建一维数据
arr = np.array([1,2,6,8,9,10,12])
a = arr[4]             #获取第5个元素
print(a)
#一维数组切片
b1 = arr[1:6:2]        #b1数组[ 2 8 10]
b2 = arr[:5]           #b2数组[1 2 6 8 9]
b3 = arr[2:]           #b3数组[ 6  8  9 10 12]
print(b1,b2,b3)
#修改数组中元素
arr[1:3] = 20,30
print(arr)
#创建二维数据
arr=np.array([[0,1,2,3,4],[5,6,7,8,9]])
a = arr[1,3]
print(a)
#二维数组切片
b1 = arr[:2,1:3]
b2 = arr[1:,2:5]
b3 = arr[:2:2,:3:2]
b4 = arr[...,1:3]
print(b1,b2,b3,b4)
#修改数组中元素
arr[:2:2,:3:2]=44,55
print(arr)

整数索引

整数索引就是从两个序列的对应位置取出两个整数来组成行下标和列下标。示例代码 example2 如下。
# -*- coding: UTF-8 -*-
import numpy as np
a = np.array([[1,2,3], [4,5,6],[7,8,9]])
b = a[[(0,1,2),(0,1,0)]]        #获取a[0,0],a[1,1],a[2,0]元素组成数组b
print (b)
#获取a数组上下左右四个角上的元素
b = a[[(0,0,2,2),(0,2,0,2)]]    #获取a[0,0],a[0,2],a[2,0],a[2,2]元素
print(b)

布尔值索引

当结果对象是布尔运算(例如比较运算符)的结果时,将使用布尔值索引。示例代码 example3 如下。
# -*- coding: UTF-8 -*-
import numpy as np
a = np.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]
print  ('a数组是:',a)
# 生成大于6的元素组成数组
b = a[a>5]
print ('大于6的元素是:',b)

注意:
① 操作原数组的子序列的时候,实际上就是操作原数组的数据。这就意味着数组中的数据没有被复制,任何在其子序列上的操作都会映射到原数组上。
② 整数索引和布尔值索引属于高级索引,高级索引始终返回数据的副本,原数组是不会变化的。