NumPy快速入门笔记

栏目: Python · 发布时间: 6年前

内容简介:NumPy快速入门笔记

我正以 Python 作为突破口,入门机器学习相关知识。出于机器学习实践过程中的需要,我快速了解了一下 NumPy 这个科学计算库的使用方法。下面记录相关学习笔记。

简介

NumPy 是一个科学计算库。结合 Python 生态系统的其它库,如 SciPymatplotlib 等, NumPy 可以玩出比 MatLAB 还出彩的花样。

NumPy 的主要核心在于其定义了一个强大的N维数组类型 ndarray 。本文内容全部围绕着这个类型展开,主要参考 NumPy 官网的QuickStart教程和BroadCast文档进行讲述, 对于我认为很基础的内容可能会进行省略,若有不理解的地方请参考源文档。

围绕N维数组, NumPy 定义了许多函数,例如 numpy.sinnumpy.cosnumpy.exp 等。接下来的内容中将用 np 表示 numpy 模块,即假设我们已经执行了下面代码:

import numpy as np

认识 ndarray

ndarray 是一个N维数组,我觉得它跟线性代数中介绍的空间的概念很贴近。

创建 ndarray 实例

手动创建 ndarray 实例可以使用 np.array 函数。

array = np.array([1,2,3]) # 创建一个含有三个元素一维数组

注意这个函数的参数是一个list列表对象,而不是多个数字。即 np.array(1,2,3) 是错误的。如果传递的参数list是一个嵌套的list, np.array 函数可以自动根据其嵌套方式生成多维数组。另外还可以通过关键词参数 dtype ,定义数组元素的类型。默认地,新数组的元素类型为 np.float64

除了 np.array 函数,我们还可以用 np.zerosnp.onesnp.emptynp.arangenp.linspacenp.fromfunction 等函数创建数组对象。

下面看几个例子:

np.zeros((3,4)) # 创建元素为0的3行4列的数组  
np.ones((2,3,4), dtype=np.int16) # 创建元素为1的2x3x4数组,类型为np.int16  
np.empty((3,4)) # 创建元素为随机数的3x4数组  
np.arange(1, 10, 1) # 在1到10中以1为间距提取实数组成一维数组  
np.arange(10) # 省略方式,功能同上  
np.linspace(0, 10, 5) # 在0到10中等间距提取5个实数组成一维数组  
...

基本操作

ndarray 基本操作指的是加减乘除等运算。除了下面几点需要注意,没太多内容。

  • 参与运算的数组元素类型不一致的,输出结果的元素类型将为精度更高的类型。
  • 维度相同的数组的操作一般(矩阵点乘叉乘等除外)遵循对应元素分别相操作,生成的新元素组成结果。
  • 维度不相同的数组如果符合 NumPy 的广播规则,将按广播定义的规则进行操作;否则抛出异常。(文章最后会有关于广播规则的介绍)
  • 设有数组A、B,那么A*B是元素乘积,即每个元素对应相乘;而A.dot(B)或np.dot(A,B)表示矩阵点乘。

访问数组的元素与切片

一维数组的访问方式跟 Python 的list列表对象的访问方式一样。 通过逗号分隔索引组成的列表的方式访问。每个索引值从高到低对应数组的维度。

访问多维数组的元素

访问元素的索引是一个整数,表示某个维度中的下标。

设有多维数组A为[[[1,2],[3,4]],[[5,6],[7,8]]],下面结合例子辅助理解:

  • A[0]: 访问数组A第一维度的第一个元素,为[[1,2],[3,4]]。
  • A[1,1]: 先取数组A第一维度的第二个元素B(是一个第二维度的元素),然后取B其中的第二个元素,为数组[7,8]。
  • A[1,1,1]: 原理如上,结果为标量8。

访问多维数组的切片

访问切片用冒号分割整数的方式表示索引,形如x:y:z的样子,x表示开始下标(包含),y表示结束下标(不包含),z为步长(省略为1)。 还可以用 ... 符号作为尽可能多全选切片索引的省略标记。

  • A[0:1]: 返回“第一维元素中所有下标大于等于0且小于1的元素”组成的新数组。它依旧是一个三维数组,为[[[1, 2],[3, 4]]]
  • A[0:1:2]: 在这个例子中结果同上,最后一个2是选择的步长,因为我们最多只有两个元素,所以在选择了下标为0的元素后步长加2就没有其他元素了。
  • A[0:1,0:1]: 返回“第一维元素中所有下标大于等于0且小于1,并且第二维元素所有下标大于等于0且小于1的元素”组成的新数组。它依旧是一个三维数组,为[[[1, 2]]]
  • A[...,0:1]: 省略号表示尽可能多的全选切片,等同于A[:,:,0:1],所以结果为[[[1],[3]],[[5],[7]]]

同时访问元素和切片

这种情况真它大爷的是一个让人很难解释的过程。只能总结一下我认识的规律。针对这种情况,我的做法是补全所有遗漏索引,数一下出现元素索引的数目即可判断结果将会降多少个维度。然后按照上面访问切片的理解选取每个维度中选中切片。

  • A[0:1,0]: 等同补全索引后的A[0:1,0,:],结果是降了一个维度的[[1, 2]]。选取的条件要同时满足: “第一维度下标大于等于0且小于1,并且第三维度全选”的切片,而“第二维度取下标为0”的元素。

数组的变形、拼接、分割、浅拷贝和深拷贝

这部分内容也是想略过的。下面简单提及相关的函数,使用时通过 Pythonhelp 函数可以获取更详细的介绍。同样地,假设我们已经有了数组A。

  • 变形: A.ravel() 返回A扁平化后的一维数组; A.T 返回A的转置; A.reshape(indics) 返回A变形后的新数组; A.resize(indics) 修改A的维度,不返回新数组。
  • 拼接: np.hstack(A,...)np.vstack(A,...) 等。
  • 分割: np.hsplit(A, indics)np.vsplit(A, indics) 等。
  • 浅拷贝: B = A.view()
  • 深拷贝: B = np.copy(A) 或者 B = A.copy()

NumPy 的广播规则

当对两个数组进行某种操作的时候,如果这两个数组的维度是一样的,通常按照操作的定义完成操作即可。但是总会出现两个数组维度不一样的场景,这是怎么办?

NumPy 认为部分维度不一样的数组间的操作是有意义的。针对这种有意义的情况,引入了广播的概念,从而实现操作。下面总结一下我对广播的理解。

  1. 对输入的两个数组a和b,先用1给维度数目小的数组在前面补全它的shape。例如现在有 a.shape(1,3,4)b.shape(4) ,则 b 补全后为 (1, 1, 4)

  2. 从最低维度向最高维度,逐一比对在这个维度中的长度。例如: a.shape(3,4)b.shape(2,1) 。先比对4和1,然后比对3和2,以此类推。

  3. 比对结果若是相等,或者其中有一个数为1,则可以使用广播。否则报ValueError异常。而操作的输出结果的各个维度值是其中大的值。例如: a.shape(3,4)b.shape(3,1) ,对比结果可以使用广播,现在让二者相加,则 (a+b).shape(3,4)

  4. 符合广播规则,将执行最终操作。根据维度比对的结果,把维度小的向维度大的扩展。扩展的方法:维度值一样保持不变;维度不一样时,维度小的数组的值肯定是1,这时候则是以当前维度的这个唯一元素作为整体,其他空缺的元素的值都用这个值参与计算。

最后,看一个例子:

a = np.array([[[1],[1],[1]],[[1],[1],[1]]])  
b = np.array([[1,2],[1,2],[1,2]])

有两个数组a和b,他们的维度分别为 (2,3,1)(3,2) 。很明显,两个数组的维度不一样了。我们需要扩展b的维度,扩展后是 (1,3,2) 。然后从右边低维向左边高维对 (2,3,1)(1,3,2) 进行比对,发现符合广播的规则。

我们发现数组a的最低维是1,需要扩展为2。这个维度的元素只有一个标量1,它应该要有两个元素,所以扩展后就是: [[[1,1],[1,1],[1,1]],[[1,1],[1,1],[1,1]]]

同样地,数组b的最高维度是1,需要扩展为2。这个维度的元素是一个数组 [[1,2],[1,2],[1,2]] ,因此我们复用这个元素,扩展结果为: [[[1,2],[1,2],[1,2]],[[1,2],[1,2],[1,2]]]

最后用这两个扩展后的结果进行操作。

注意:上面总结提到的扩展在 NumPy 实际计算的时候是虚拟实现的,并不会生成额外的对象或占用额外的内存,因此它的效率是有保证的。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python网络编程攻略

Python网络编程攻略

萨卡尔 (Dr.M.O.Faruque Sarker) / 安道 / 人民邮电出版社 / 2014-12-1 / 45.00元

开发TCP/IP网络客户端和服务器应用 管理本地设备的IPv4/IPv6网络接口 使用HTTP和HTTPS协议编写用途多、效率高的Web客户端 编写可使用常见电子邮件协议的电子邮件客户端 通过Telnet和SSH连接执行远程系统管理任务 使用Web服务与流行的网站交互 监控并分析重要的常见网络安全漏洞一起来看看 《Python网络编程攻略》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具