NumPy快速入门笔记
我正以Python作为突破口,入门机器学习相关知识。出于机器学习实践过程中的需要,我快速了解了一下NumPy这个科学计算库的使用方法。下面记录相关学习笔记。
简介
NumPy是一个科学计算库。结合Python生态系统的其它库,如SciPy、matplotlib等,NumPy可以玩出比MatLAB还出彩的花样。
NumPy的主要核心在于其定义了一个强大的N维数组类型ndarray。本文内容全部围绕着这个类型展开,主要参考NumPy官网的QuickStart教程和BroadCast文档进行讲述,
对于我认为很基础的内容可能会进行省略,若有不理解的地方请参考源文档。
围绕N维数组,NumPy定义了许多函数,例如numpy.sin、numpy.cos、numpy.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.zeros、np.ones、np.empty、np.arange、np.linspace、np.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”的元素。
数组的变形、拼接、分割、浅拷贝和深拷贝
这部分内容也是想略过的。下面简单提及相关的函数,使用时通过Python的help函数可以获取更详细的介绍。同样地,假设我们已经有了数组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认为部分维度不一样的数组间的操作是有意义的。针对这种有意义的情况,引入了广播的概念,从而实现操作。下面总结一下我对广播的理解。
对输入的两个数组a和b,先用1给维度数目小的数组在前面补全它的shape。例如现在有
a.shape为(1,3,4),b.shape为(4),则b补全后为(1, 1, 4)。从最低维度向最高维度,逐一比对在这个维度中的长度。例如:
a.shape为(3,4),b.shape为(2,1)。先比对4和1,然后比对3和2,以此类推。比对结果若是相等,或者其中有一个数为1,则可以使用广播。否则报ValueError异常。而操作的输出结果的各个维度值是其中大的值。例如:
a.shape为(3,4),b.shape为(3,1),对比结果可以使用广播,现在让二者相加,则(a+b).shape为(3,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实际计算的时候是虚拟实现的,并不会生成额外的对象或占用额外的内存,因此它的效率是有保证的。
本文来自同步博客
NumPy快速入门笔记的更多相关文章
- numpy快速入门
numpy快速入门 numpy是python的科学计算的核心库,很多更高层次的库都基于numpy.博主不太喜欢重量级的MATLAB,于是用numpy进行科学计算成为了不二选择. 本文主要参考Scipy ...
- C#快速入门笔记(1)——基础语法
C#快速入门笔记(1)——基础语法 总体框架:
- keras搭建神经网络快速入门笔记
之前学习了tensorflow2.0的小伙伴可能会遇到一些问题,就是在读论文中的代码和一些实战项目往往使用keras+tensorflow1.0搭建, 所以本次和大家一起分享keras如何搭建神经网络 ...
- C++ 快速入门笔记:进阶编程
C++入门笔记:高级编程 文件和流 打开文件 void open (const char *filename, ios::openmode mode); ios::app 追加模式.所有写入都追加到文 ...
- Pandas快速入门笔记
我正以Python作为突破口,入门机器学习相关知识.出于机器学习实践过程中的需要,我快速了解了一下提供了类似关系型或标签型数据结构的Pandas的使用方法.下面记录相关学习笔记. 数据结构 Panda ...
- Matplotlib快速入门笔记
我正以Python作为突破口,入门机器学习相关知识.出于机器学习实践过程中的需要,快速了解了一下matplotlib绘图库.下图是我学习过程中整理的一些概念. 本文将以该图为线索梳理相关概念. 简介 ...
- Spring Boot 快速入门笔记
Spirng boot笔记 简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发 ...
- bootstrap快速入门笔记(八)-按钮,响应式图片
一,默认样式:.btn-default , .btn-primary , .btn-success ,.btn-info, btn-warning ,btn-link 二,尺寸:.btn-lg, . ...
- bootstrap快速入门笔记(四)-less用法指南, mixin和变量
一,less变量,less文件 1.bootstrap.less 这是主要的 Less 文件.该文件中导入了一些其他的 less 文件.该文件中没有任何代码. 2.forms.less 这个 Less ...
随机推荐
- zoj 3494:BCD Code
Description Binary-coded decimal (BCD) is an encoding for decimal numbers in which each digit is rep ...
- hdu_1698Just a Hook(线段树)
hdu_1698Just a Hook(线段树) 标签: 线段树 题目链接 题意: 一个英雄的技能是发射一个长度为n的金属链,初始的金属链都是铁做的,标记为1,我们可以对于某个区间修改它的金属材质,如 ...
- flume1.8 Interceptors拦截器(五)
1. Flume Interceptors Flume有能力修改/删除流程中的events.这是在拦截器(interceptor)的帮助下完成的.拦截器(Interceptors)是实现org.apa ...
- C# 构造器总结
在C#中,构造器分为实例构造器和类型构造器, 一.实例构造器 构造引用类型的对象时,在调用实例 构造器之前,为对象分配的内存总是归0,没有被构造器显示重写的字段都保证获得0或null的值 在一个类中, ...
- Generator函数异步应用
转载请注明出处: Generator函数异步应用 上一篇文章详细的介绍了Generator函数的语法,这篇文章来说一下如何使用Generator函数来实现异步编程. 或许用Generator函数来实现 ...
- ASP.NET没有魔法——ASP.NET MVC & 分层 代码篇
上一篇文章对如何规范使用ASP.NET进行了介绍,本章内容将根据上一篇得出的结论来修改博客应用的代码. 代码分层 综合考虑将博客应用代码分为以下几个层次: ○ 模型:代表应用程序中的数据模型,与数据库 ...
- Docker+Jenkins持续集成环境(3)集成PMD、FindBugs、Checkstyle静态代码检查工具并邮件发送检查结果
为了规范代码,我们一般会集成静态代码检测工具,比如PMD.FindBugs.Checkstyle,那么Jenkins如何集成这些检查工具,并把检查结果放到构建邮件里呢? 今天做了调研和实现,过程如下 ...
- 如何开发由Create-React-App 引导的应用(三)
此文章是翻译How to develop apps bootstrapped with Create React App 官方文档 系列文章 如何开发由Create-React-App 引导的应用 如 ...
- 《You dont know JS》值相关总结
值 一:和数组相关的几个需要关注的点 数组可以容纳任何类型的值. 数组声明时不需要预先设置大小.可以动态改变. 使用delete运算符可以将数组中的某个元素删除,但是这个操作不会改变数组的length ...
- Java 对二值化图片识别连通域
用Java 对 已经 二值化了的图片 标记连通域 每块的连通域都标记不一样的数字 public static void main(String [] args) throws IOException ...