3. NumPy的索引与切片
Numpy产生的数组或者说矩阵的访问和Python里的有序集合的访问方式一样,可以通过索引访问某个位置上的元素值或者通过切片访问某范围的数据。
3. 1索引index
给出访问的位置,即可访问某位置上的数据值,位置信息也称索引,通过索引访问数组里的某位置上的数据的语法格式:
numpy的ndarray对象[位置]
这种通过索引的方式可以使用或者访问数组里的某个元素的值,即可作为表达式的左值(被新赋值、写)或者右值(参与计算、读)。
举例如下:
from numpy import *
a = arange(24)
print a
#a[3] = 99
print a[3]
b = a.reshape((2, 3, 4))
print b
# 给出索引“坐标”的两种方式
print b[0][2][3]
print b[0, 2, 3]
程序的执行结果:
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
3
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
11
11
语句print a[3]
是打印了a的第3个元素的值,系读取数组里的某位置上的数据;被注释掉的a[3]= 99
是左值表达式,被赋值。
reshape函数 可以改变数组的型,即维度,原来a数组是一位数组,通过NumPy的reshape函数将a数组变为b数组,b是三维数组有三个维度,b的各维度为[2, 3, 4]。
而对于多维数组b想访问11这个值,需要给出三维的索引坐标即b[0][2][3]
或者b[0, 2, 3]
这两种表达方式都可以。
3.2 切片slice
切片的基本概念在Python的第7章的第一节次里已经详细的介绍过了。以一位数组为例展示其语法结构,如下所示:
数组名[起点:终点:步长]
切片含起点不含终点值,从起点起向终点取数据,每步长个数据视为一组,通过切片取回的值是每组的第一个数据值构成的集合,这里是对NumPy的数组取切片,那么结果集还是数组。
from numpy import *
a = arange(24)
print a
b = a.reshape((2, 3, 4))
print "*" * 20
print b
print "*" * 20
print b[1,1:2,1:]
程序的执行结果:
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
# 数组b
********************
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
# 切片b[1,1:2,1:]
********************
[[17 18 19]]
如果三维数组(矩阵)的切片不太好理解,我们可以换二维的来再举一个例子:
from numpy import *
a = arange(12)
print a
b = a.reshape((3, 4))
print "*" * 20
print b
print "*" * 20
print b[1 : , 1 : 3]
程序执行结果:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
********************
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
********************
[[ 5 6]
[ 9 10]]
语句a.reshape((3, 4))
将基于a数组产生一个形为(3, 4)的二维数组(矩阵)b,可以通过打印b的shape属性查看b的形状print b.shape
。
3.2.1步长
在使用切片的时候可以每隔多少个取第一个数据即步长step。
from numpy import *
a = arange(12)
print a
b = a.reshape((3, 4))
print "*" * 20
print b
print "*" * 20
print b[1 : ,::2]
程序的结果:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
********************
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
********************
[[ 4 6]
[ 8 10]]
这里的step = 2。上边的例子对b数组的行没有用到步长,实际默认步长为1,对列s设置的不成是2,下面的例子行和列都用到了步长。
from numpy import *
a = arange(24)
print a
b = a.reshape((6, 4))
print "*" * 20
print b
print "*" * 20
print b[1::2 ,::2]
程序的执行结果如下所示:
#数组a
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
#数组b
********************
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]
#切片b[1::2 ,::2]
********************
[[ 4 6]
[12 14]
[20 22]]
3.3 切片的重要性
切片很重要,在opencv里切图即一幅图切出一部分,可以用切片给出切图的范围,所以这部分的深入理解才是。