机器学习之计算工具库(一)

标题

Numpy

ndarray

ndarray数据类型

修改ndarray的形状

ndarray索引和切片

ndarray的转置与轴变换

通用函数

ndarray与标量的运算

Numpy

NumPy是用Python进行科学计算的基本软件包。它包含以下内容:

一个强大的N维数组对象

复杂的(广播)功能

用于集成C / C ++和Fortran代码的工具

有用的线性代数,傅里叶变换和随机数能力

用于读写磁盘数据以及操作内存映射文件的工具

NumPy的优势在于NumPy底层使用C语言编写,其对数组的操作速度不受Python解释器的限制,效率远高于纯Python代码。并且结合Python脚本语言的特点,使得代码比起其他语言更简洁易读。除了明显的科学用途外,NumPy还可以用作通用数据的高效多维容器。任意的数据类型可以被定义。这使得NumPy能够与各种各样的数据库无缝,快速地整合。

ndarray

ndarray是一个N维齐次同构数组对象,每个数组都有一个shapedtype属性,shape描述的是ndarray的形状,而dtype则描述ndarray里面元素的数据类型。

创建ndarray

通常创建ndarray会用如下几种方法

函数

说明

array

将输入数据(列表、元祖、数组或其他序列类型)转换为ndarray。要么有numpy自己推断dtype,要么显示的指定dtype。默认直接复制输入数据

asarray

将输入转换为ndarray,如果输入本身就是一个ndarray则不进行复制。

arange

类似内置的range,但返回的是ndarray数组而不是列表

ones

ones_like

根据指定的形状和dtype创建一个全1的数组。ones_like接受另一个数组为参数,并根据其形状和type创建全1数组

zero

zero_like

类似one和ones_like,但产生数组的值全为0

empty

empty_like

和上面类似,不过只分配律内存空间,数组里的值不作初始化

eye

identity

创建一个NxN的单位矩阵

下面是创建ndarray的例子

可以看到numpy根据输入的嵌套列表,生成了一个二维数组,每一维有三个元素,而且我们可以看到该数组元素的数据类型均为int64(因为没有显式的指定dtype参数,所以numpy自己推断了int64这个数据类型,int64为64位整型)

ndarray数据类型

dtype含有将ndarray解释为特定数据类型的所需的信息,数据的类型命名有规律,均为类型名+位宽(一个字节有8个位宽)如上面例子中的int64。dytpe有整型、浮点数、字符串、复数、布尔值、Python对象等等。

如果你没有在创建ndarray数组时显式的指明dtype,你仍可以通过astype(type)方法修改数据类型为type,但是使用astype会返回一个新的数组,浪费额外的内存,因此建议在创建ndarray数组的时候指定数据对象。(注意浮点数转化为整型数会把小数部分截断)

修改ndarray的形状

shape属性描述了ndarray数组的形状ndarray.shape会返回描述形状而元祖,元祖内元素的个数表示数组有多少个维度,元素的值描述了某个维度的长度。在创建ndarray数组的时候我们可以用一个元祖指定shape参数的取值来控制数组的形状。或者在创建数组之后,直接对数组的shape属性赋值或者使用reshape()方法来返回一个指定形状的新数组。

在使用reshape的时候若你指定传入-1为参数,那么返回的数组将会是1维,

当你指定了n-1维的值后,剩下一维的大小可以传入-1,由numpy自己计算出该维度的大小

reshape()方法虽然可以改变数组的形状,但由于数组元素的个数是恒定不变的,而且显然数组元素个数为各个维度大小的乘积。但在有些时候,我们需要给数组添加一些新的元素。numpy中有column_stack()row_stack()方法,可以把两个数组合并,达到增加元素的效果。

column_stack()为例,该函数接受一个元祖作为参数将元祖内的数组按列堆叠,上例将形状为(2,1)的数组堆叠到array,显然按列堆叠必须要行数必须相等。大于二维的数组若想要成功按列堆叠,则需要除列以外所有维度的大小相等。

类似的函数或类还有concatenate()、vstack()、r_、c_等等,其中concatenate()为最一般的连接方法,它可以指定按某一个轴进行数组的合并。

除了合并,还可以用split()函数传入指定轴以及切分点的索引值拆分数组(传入n个切分索引则返回n+1个数组),类似的方法还有hsplit() 、vsplit() 、dsplit()有兴趣的朋友可以去查看官方文档。

ndarray索引和切片

Python列表的索引和切片操作在ndarray上仍然适用。但是要注意ndarray的切片返回的是数组的视图而非副本,如果你想要获得副本,这需要显式的调用copy()方法

以上代码可以选取除最后一列的其他元素,可以看到在numpy里,所有维度的索引可以写在一个中括号内,并且用逗号隔开(分别写在多个中括号也是可以的,这种写法和Python列表索引的写法相同)。

ndarray还有着特殊的索引方式,分布是布尔型索引花式索引。

布尔型索引就是在中括号内放入布尔型数组,数组会根据布尔型数组的真值来选择数据。

上例中在索引里加入布尔表达式,可以生成与原数组形状相同的布尔型数组,如上图所示array>3返回的是是一个与原数组形状相同的布尔型数组。原数组对应位置的元素的值为该元素对于给定布尔表达式的真值。因此只有4,5,6对应的位置应位置的取值才为True。若把布尔型数组放入索引,就可以按照布尔数组来索引元素了。(注意布尔型数组的长度必须与被索引轴的长度相等)

花式索引就是把一个指定顺序的整数顺序的列表或者ndarray数组放入中括号内,就可以按照特定顺序选取子集例如我想选第0列和第2列的全部元素,那么就可以向下面那样进行索引。

或者我想先选取第2列再选取第0列,只须修改列表里元素的顺序即可。

numpy索引的方法有很多,但是各种索引方式之间的效率和空间是不一样的。例如我们现在有一个比较大的数组,我们打算每隔10个行选取1行,则可以有以下两种方式。

可以看到使用切片会比花式数组快两个数量级,这是因为切片返回的是原数组的视图,修改视图会修改原数组。但是花式索引返回的是却是一个新的数组。实际上使用切片再显式的拷贝也比使用花式数组要快。故等步长选取数据时优先使用切片会有更好的性能。

但你选取的数据不是按等步长的选择时,可以使用np.take()方法,他接受一个数组,索引数组以及轴作为参数,如下例所示

使用take()方法可以比使用花式索引快那么一点点。在使用布尔型索引按某一轴的时候,使用np.compress()的效率会更高。(np.compress()用法和take一样)。

ndarray的转置与轴变换

若想实现数组的转置可以使用transpose()方法接受描述轴顺序的元祖作为参数,并根据这一元祖对元素重新排序。例如一个二维数组的轴原来为(0,1),当你改变轴的顺序为

(1,0)即可实现转置。

也可以直接使用.T简单转置

在处理二维数组的时候使用.T.transpose()并没有差异,但是.transpose()可以实现更复杂的轴变换,而.T值能实现轴的按逆序来进行轴变换。(注意一维数组的转置为本身)

通用函数

通用函数是一种对ndarray中的数据进行元素级运算的函数。这些函数非常好上手,都是一些看到名字就知道作用的函数,例如absfbs、sqrt

、exp等等。numpy的数学函数库非常的丰富,在此就不一一说明,以下是例子。

可以看到每一个元素都被开平方。

ndarray与标量之间运算

ndarray支持数组直接用运算符来与标量运算。运算的效果为数组的每一个元素都与标量进行运算,这一点符合和我们正常的使用习惯。并且对于形状相同的两个数组,使用运算符直接运算,会转化为对应位置元素之间的运算,一下是例子。

可以看到原数组的每一个元素的值都加1了。

ndarray的“三目运算符”

在numpy中有一个where函数,常用于对特定数据进行修改或者选取。其用法有点像C语言中的三目运算符。

where()函数接受三个参数,第一个是逻辑表达式,若逻辑表达式为真则选取第二个参数,否则选取第三个参数。第二个和第三个参数可以是标量也可以是数组。本质上就是一个if...else...语句快。

如上例所示,但arr1arr2对应位置的元素进行比较,若arr1中对应位置的元素大于arr2对应位置的元素,则选取arr1中的元素,否则选取arr2中的元素。故结果为array( [ 3,2,3] )

本期为大家简单介绍了numpy的部分内容,下期Python基础将会更深入地为大家介绍numpy的使用方法。

参考资料:

《利用Python进行数据分析》 机械工业出版社 Wes McKinney著 唐学掏等译

以及网上各位大佬的博文

AI遇见机器学习

mltoai

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180112G10PVM00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券