Numpy学习代码集(一)——切片,索引,组合,分割

第一章

(1) 创建一个多维数组。
(2) 显示该数组的维度。

In: m = array([arange(2), arange(2)]) 
In: m 
Out: array([[0, 1],         
			[0, 1]]) 

In: m.shape 
Out: (2, 2) 

索引元素:

In: a[0,0]  
Out: 1  
In: a[0,1]  
Out: 2 

nunpy数据类型:
在这里插入图片描述

定义类型:

In: arange(7, dtype=uint16) 
Out: array([0, 1, 2, 3, 4, 5, 6], dtype=uint16) 

数据类型对象是numpy.dtype类的实例。如前所述,NumPy数组是有数据类型的,更确切 地说,NumPy数组中的每一个元素均为相同的数据类型。数据类型对象可以给出单个数组元素在 内存中占用的字节数,即dtype类的itemsize属性

In: a.dtype.itemsize  
Out: 8 

2.2.4 字符编码

NumPy可以使用字符编码来表示数据类型,这是为了兼容NumPy的前身Numeric。我不推荐 使用字符编码,但有时会用到,因此下面还是列出了字符编码的对应表。读者应该优先使用dtype 对象来表示数据类型,而不是这些字符编码
在这里插入图片描述
下面的代码创建了一个单精度浮点数数组:

In: arange(7, dtype='f') 
Out: array([ 0., 1., 2., 3., 4., 5., 6.], dtype=float32])

2.4 一维数组的索引和切片

一维数组的切片操作与Python列表的切片操作很相似。例如,我们可以用下标3~7来选取元 素3~6:
In: a = arange(9) 
In: a[3:7] 
Out: array([3, 4, 5, 6]) 

#也可以用下标0~7,以2为步长选取元素: 

In: a[:7:2] Out: array([0, 2, 4, 6])

#和Python中一样,我们也可以利用负数下标翻转数组:
 
In: a[::-1] 
Out: array([8, 7, 6, 5, 4, 3, 2, 1, 0]) 

2.5 多维数组的切片和索引

ndarray支持在多维数组上的切片操作。为了方便起见,我们可以用一个省略号(…)来 表示遍历剩下的维度。
(1) 举例来说,我们先用arange函数创建一个数组并改变其维度,使之变成一个三维数组

In: b = arange(24).reshape(2,3,4) 
In: b.shape 
Out: (2, 3, 4) 
In: b 
Out: array([[[ 0, 1, 2, 3],          [ 4, 5, 6, 7],         [ 8, 9,10,11]],        [[12, 13, 14, 15],         [16, 17, 18, 19],         [20, 21, 22, 23]]]) 

(2) 我们可以用三维坐标来选定任意一个房间

In: b[0,0,0]  
Out: 0 

(3) 如果我们不关心楼层,也就是说要选取所有楼层的第1行、第1列的房间,那么可以将第1 个下标用英文标点的冒号:来代替:

In: b[:,0,0] Out: array([ 0, 12]) 
In: b[0] 
Out: array([[ 0, 1, 2, 3],         [ 4, 5, 6, 7],         [ 8, 9,10,11]]) 

我们还可以这样写,选取第1层楼的所有房间:

In: b[0, :, :] 
Out: array([[ 0, 1, 2, 3],         [ 4, 5, 6, 7],         [ 8, 9,10,11]]) 

多个冒号可以用一个省略号(…)来代替,因此上面的代码等价于:

In: b[0, ...] 
Out: array([[ 0, 1, 2, 3],            [ 4, 5, 6, 7],         [ 8, 9, 10, 11]])

进而可以选取第1层楼、第2排的所有房间

In: b[0,1] Out: array([4, 5, 6, 7]) 

(4) 再进一步,我们可以在上面的数组切片中间隔地选定元素:

In: b[0,1,::2]  Out: array([4, 6])

(5) 如果要选取所有楼层的位于第2列的房间,即不指定楼层和行号,用如下代码即可:

In: b[...,1]  
Out: array([[ 1, 5, 9],         [13,17,21]]) 

类似地,我们可以选取所有位于第2行的房间,而不指定楼层和列号

In: b[:,1]  
Out: array([[ 4, 5, 6, 7],         [16,17,18,19]]) 

如果要选取第1层楼的所有位于第2列的房间,在对应的两个维度上指定即可:

In: b[0,:,1] 
Out: array([1, 5, 9]) 

(6) 如果要选取第1层楼的后一列的所有房间,使用如下代码:

In: b[0,:,-1] 
Out: array([ 3, 7, 11]) 

如果要反向选取第1层楼的后一列的所有房间,使用如下代码:

In: b[0,::-1, -1] 
Out: array([11, 7, 3]) 

在该数组切片中间隔地选定元素:

In: b[0,::2,-1]  
Out: array([ 3, 11]) 

如果在多维数组中执行翻转一维数组的命令,将在前面的维度上翻转元素的顺序,在我们 的例子中将把第1层楼和第2层楼的房间交换:

In: b[::-1]  
Out: array([[[12,13,14,15],         [16,17,18,19],         [20,21,22,23],        [[ 0, 1, 2, 3], [ 4, 5, 6, 7],         [ 8, 9,10,11]]]) 

2.6 动手实践:改变数组的维度

(1) ravel 我们可以用ravel函数完成展平的操作:

In: b
Out: array([[[ 0, 1, 2, 3],          [ 4, 5, 6, 7],          [ 8, 9,10,11]],         [[12,13,14,15],          [16,17,18,19],          [20,21,22,23]]])  

In: b.ravel()  
Out: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])

(2) flatten 这个函数恰如其名,flatten就是展平的意思,与ravel函数的功能相同。 不过,flatten函数会请求分配内存来保存结果,而ravel函数只是返回数组的一个视图(view):

In: b.flatten()  
Out: array([ 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) 用元组设置维度除了可以使用reshape函数,我们也可以直接用一个正整数元组来设 置数组的维度,如下所示:

In: b.shape = (6,4) 
In: b  
Out:  array([ 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成了一个6×4的多维数组。

(4) transpose 在线性代数中,转置矩阵是很常见的操作。对于多维数组,我们也可以这样做:

In: b.transpose()  
Out: array([[ 0, 4, 8, 12, 16, 20],         [ 1, 5, 9, 13, 17, 21],         [ 2, 6,10, 14, 18, 22],        [ 3, 7,11, 15, 19, 23]]) 

(5) resize resize和reshape函数的功能一样,但resize会直接修改所操作的数组:

In: b.resize((2,12)) 
In: b 
Out: array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],        [12,13,14,15,16,17,18,19,20,21, 22, 23]]) 

2.7 数组的组合

NumPy数组有水平组合、垂直组合和深度组合等多种组合方式,我们将使用vstack、 dstack、hstack、column_stack、row_stack以及concatenate函数来完成数组的组合

首先,我们来创建一些数组:

In: a = arange(9).reshape(3,3) 
In: a 
Out: array([[0, 1, 2],         [3, 4, 5],         [6, 7, 8]])  
In: b = 2 * a  
In: b  
Out: array([[ 0, 2, 4],         [ 6, 8, 10],         [12, 14,16]])

(1) 水平组合 我们先从水平组合开始练习。将ndarray对象构成的元组作为参数,传给hstack函数。如下所示:

In: hstack((a, b))  
Out: array([[ 0, 1, 2, 0, 2, 4],         [ 3, 4, 5, 6, 8,10],         [ 6, 7, 8,12,14,16]]) 

我们也可以用concatenate函数来实现同样的效果,如下所示:

In: concatenate((a, b), axis=1)  
Out: array([[ 0, 1, 2, 0, 2, 4],         [ 3, 4, 5, 6, 8,10],          [ 6, 7, 8,12,14,16]]) 

(2) 垂直组合 垂直组合同样需要构造一个元组作为参数,只不过这次的函数变成了 vstack。如下所示:

In: vstack((a, b))  
Out: array([[ 0, 1, 2],        [ 3, 4, 5],        [ 6, 7, 8],        [ 0, 2, 4],        [ 6, 8,10],        [12,14,16]]) 

同样,我们将concatenate函数的axis参数设置为0即可实现同样的效果。这也是axis参 数的默认值:

In: concatenatel((a, b), axis = 0)  
Out: array([[ 0, 1, 2],        [ 3, 4, 5],        [ 6, 7, 8],        [ 0, 2, 4],        [ 6, 8,10],        [12,14,16]]) 

(3) 深度组合 将相同的元组作为参数传给dstack函数,即可完成数组的深度组合。所谓 深度组合,就是将一系列数组沿着纵轴(深度)方向进行层叠组合。举个例子,有若干张二维平 面内的图像点阵数据,我们可以将这些图像数据沿纵轴方向层叠在一起,这就形象地解释了什么 是深度组合。

In: dstack((a, b))  
Out: array([[[0, 0],         [1, 2],         [2, 4]],        [[3, 6],         [4, 8],         [5,10]],        [[6,12],         [7,14],         [8,16]]]) 

(4) 列组合 column_stack函数对于一维数组将按列方向进行组合,如下所示:

In: oned = arange(2)  
In: oned 
Out: array([0, 1])  
In: twice_oned = 2 * oned  
In: twice_oned  
Out: array([0, 2]) 
In: column_stack((oned, twice_oned))  
Out: array([[0, 0],         [1, 2]]) 

而对于二维数组,column_stack与hstack的效果是相同的:

In: column_stack((a, b))  
Out: array([[ 0, 1, 2, 0, 2, 4],         [ 3, 4, 5, 6, 8,10],         [ 6, 7, 8,12,14,16]])  
In: column_stack((a, b)) == hstack((a, b))  
Out: array([[ True, True, True, True, True, True],         [ True, True, True, True, True, True],         [ True, True, True, True, True, True]], dtype=bool) 

是的,你猜对了!我们可以用==运算符来比较两个NumPy数组,是不是很简洁?

(5) 行组合 当然,NumPy中也有按行方向进行组合的函数,它就是row_stack。对于两 个一维数组,将直接层叠起来组合成一个二维数组。

In: row_stack((oned, twice_oned))  Out: array([[0, 1],         [0, 2]]) 

对于二维数组,row_stack与vstack的效果是相同的:

In: row_stack((a, b))  
Out: array([[ 0, 1, 2],         [ 3, 4, 5],         [ 6, 7, 8],        [ 0, 2, 4],         [ 6, 8,10],         [12,14,16]])  
In: row_stack((a,b)) == vstack((a, b))  
Out: array([[ True,    True,    True],            [ True,    True,    True],            [ True,    True,    True],            [ True,    True,    True],            [ True,    True,    True],            [ True,    True,    True]], dtype=bool) 

2.9 数组的分割

NumPy数组可以进行水平、垂直或深度分割,相关的函数有hsplit、vsplit、dsplit和 split。我们可以将数组分割成相同大小的子数组,也可以指定原数组中需要分割的位置。

(1) 水平分割 下面的代码将把数组沿着水平方向分割为3个相同大小的子数组:

In: a  
Out: array([[0, 1, 2],         [3, 4, 5],         [6, 7, 8]])  
In: hsplit(a, 3)  
Out: [array([[0],         [3],          [6]]), array ([[1],         [4],         [7]]),  array ([[2],         [5],         [8]])] 

对同样的数组,调用split函数并在参数中指定参数axis=1,对比一下结果:

In: split(a, 3, axis=1)  
Out: [array([[0],         [3],          [6]]), array ([[1],         [4],         [7]]),  array ([[2],         [5],         [8]])] 

(2) 垂直分割 vsplit函数将把数组沿着垂直方向分割:

In: vsplit(a, 3) 
Out: [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])] 
同样,调用split函数并在参数中指定参数axis=0,也可以得到同样的结果:  
```python  
In: split(a, 3, axis=0) 
Out: [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])] 

(3) 深度分割 不出所料,dsplit函数将按深度方向分割数组。我们先创建一个三维数组:

In: c = arange(27).reshape(3, 3, 3) 

In: c 
Out: array([[[ 0, 1, 2],         [ 3, 4, 5],         [ 6, 7, 8]],        [[ 9,10,11],         [12,13,14],         [15,16,17]],        [[18,19,20],         [21,22,23],         [24,25,26]]]) 

In: dsplit(c, 3)  
Out: [array([[[ 0],           [ 3],           [ 6]],           [[ 9],          [12],          [15]],          [[18],          [21],          [24]]]),  array([[[ 1],         [ 4],          [ 7]],         [[10],       [13],         [16]],         [[19],         [22],         [25]]]),  array([[[ 2],         [ 5],          [ 8]],         [[11],         [14],          [17]],        [[20],          [23],         [26]]])] 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值