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

标题

Numpy

统计函数

随机

线性代数

广播

排序

结构化和记录式数组

用于数组的文件输入输出

性能建议

统计函数

numpy的函数库中也包括用于统计的函数

方法

说明

sum

对数组中全部或某轴向的元素求和。零长度的数组的sum为0

mean

求算术平均数。零长度的数组的mean为NaN

std、var

分别为标准差和方差,自由度可调(默认为n)

min

max

最大值和最小值

argmin

argmax

分别是最大元素和最小元素的索引

cumsum

所有元素的累计和

cumprod

所有元素的累计积

表格里前4行函数在使用时如果没有显式而指名某一条轴的话,则默认对象为所有元素。

指定按1轴

并且使用的时候必须要留意数组中是否有缺失值(numpy.NAN),若数组有缺失值,则结果也会是nan。

表格的最后两个函数的元素的返回值为一维数组,其元素为原数组逐个累加(乘)的结果。

若数组中存在缺失值,则自第一个缺失值之后的值都是nan

有些时候即使数组中有缺失值,但是这些缺失值实际上可以忽略。numpy还有一些忽略缺失值的统计函数,他们都是以nan开头,例如.nansum()可以忽略缺失值进行求和,用法和sum是一样的。

有些时候,我们需要判断有没有缺失值,要知道在数据很多的情况下判断有没有缺失值靠肉眼是不可能的(数据太多,Python也不会将数据全部显示),因此我们可以用.isnan()函数来进行判断数据中是否存在缺失值。虽说可以直接使用nan开头的统计函数,但nan开头的统计函数的执行效率比普通统计函数慢得多。

随机

numpy中也提供了random模块,总的来说提供了随机整型数,随机浮点数,随机正态分布,随机选择等类型的随机数。以下是例子

用以上方法给以生成[ -10,10)的随机整型数,若不指定下限,下限默认为0,若不指定size默认返回单个数据。

以上方法可以生成[ 0 , 1 )的随机浮点数,若不传size参数,则默认返回单个数据。

.random.randn()返回一组符合标准正态分布的的随机数。若不指定size则默认返回单个数据。

.random.choice()方法接受一维数组或者int类型,当接受的参数是一维数组,则可按照数组元素生成随机数,若传入的整型数效果与传入np.arange(int)效果相同。

还有其他的随机函数如下

函数

说明

seed

确定随机数生成器的种子

permutation

返回一个序列的随机排列

或返回一个随机排列的范围

shffle

返回一个序列就地随机排列

binomial

产生二项分布的样本值

beta

产生beta分布的样本值

chisquare

产生卡方分布的样本值

gamma

产生Gamma分布的样本值

uniform

产生在[ 0,1 )中均匀分布的样本值

shuffle()和permutation()相似,但shuffle()只能接受数组作为参数,而permutation()的参数可以是数组也可以是int,但参数为int时,等价是打乱np.arrage(int)的顺序。shuffle()就地打乱数组且返回值为None,permutation()返回一个打乱后的数组,不对原数组进行修改。在对多维数组进行随机排列的时候,只按照第一个维度进行随机排列。

seed( )用于指定随机数生成时所用算法开始的整数值。 如过每次传进去的随机整数一样,那么随机数的生成结果相同。如果不传,则系统会自动根据时间选择这个值。

线性代数

numpy线性代数相关的计算。

函数

说明

diag

以一维数组的形式返回方阵的对角线元素

dot

矩阵乘法

trace

计算对角线元素的和

det

计算矩阵行列式

eig

计算方阵的本征值和本征向量

inv

计算方阵的逆

pinv

计算矩阵的Moore-Penrose伪逆

qr

计算qr分解

svd

计算奇异值分解

solve

解线性方程组Ax=b,其中A为一个方阵

lstsq

计算Ax=b的最小二乘解

使用线性代数要注意线性代数里的一些规则,例如求行列式必须要求是方阵等等。并且要记得矩阵的乘法是.dot()函数,而不是使用*运算符。

numpy中还有一个matrix类,使用的方法更接近MATLAB中的矩阵,例如*即可实现矩阵乘法,并且矩阵还有一个I属性(矩阵的逆)。matrix的泛用性没有ndarray强,但是对于个别带有大量线性代数运算的函数,也可以先转为matrix类型,在返回之前用np.asarray(不会复制任何数据)将其转化为ndarray

广播

广播(broadcasting)是指不同形状的数组之间的算术运算的执行方式。标量和数组运算时就是一种比较简单的广播

这里我们说:在这个乘法中,标量值4广播到其他所有的元素上

广播的规则如下:

让所有输入数组都向其中shape最长的数组看齐,shape中不足的部分都通过在前面加1补齐

输出数组的shape是输入数组shape的各个轴上的最大值

如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1时,这个数组能够用来计算,否则出错

当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值

例如下面是一个(2,3)维的和(3, )数组的加法,根据以上的对齐规则,arr2和arr1的后缘维度的长度相同(都为3),符合广播规则,因此可以在轴进行广播,arr2的形状变为(1,3)

因此上面的结果相当于arr1每行元素都与arr2元素对应相加。

上图就是广播过程的一个图解,由于广播使得形状不同的数组得以运算。以下是沿其他轴广播时而例子,若我们想每一行减去每一行的平均数。

arr.mean(1)的尺寸为(4, )显然与不符合广播规则,正确的代码应该如下

由于较小数组广播维必须为1,因此用reshape改变数组的形状为(4 , 1)

但是如果reshape要增加一个维度的话,那么我必须知道各个维度的长度,这是一件非常麻烦的事,因此我们还有另外一种方法来增加一个维度

使用全切片的好处就是我们不必知道数组的维度是多少,就可以增加一个维度。而且你会发现Nonenp.newaxis是等价的。

我们还可以通过广播来赋值,例子如下

上例中将赋值广播到所有的元素,更复杂而例子如下:

这里将[1,2,3,4]沿着第1轴进行广播。

排序

ndarrayPython的列表一样,ndarraysort实例方法也是就地排序(不产生新数组),注意,如果目标数组只是某个数组的一个视图,那么原数组也会被修改。若要返回一个已排序数组的副本,则可以使用numpy.sort()。sort可以接受某个维度作为参数,即可按照该维度进行排序。虽然sort方法只能实现升序排序,但是我们只需调整切片的步长为-1即可返回数组的逆序视图。

我们还可以使用argsortlexsort实现间接排序。argsort对数组排好序后,返回索引数组。

可以看到indexer按顺序存储了排序结果的索引,当原数组使用花式索引的时候就可以得到有序结果。但是原数组并没有被修改。

lexsort也是返回一个索引数组,但是lexsort是一种多关键字排序。

上例lexsort以最后一行开始,首先对a进行排序,可以发现a中有几个元素是相同的,有着相同元素的按照索引小的在前,因此a排序后的索引数组为[ 0, 2, 4, 3, 5, 6, 1 ]。然后我们对b进行排序,排序结果为[ 2, 4, 6, 5, 3, 1, 0 ],最后的排序结果为[ 2, 0, 4, 6, 5, 3, 1 ],我们知道a中索引0和2数值相等,但是在b中索引为2的元素比索引为0的元素小,所以最终的比较结果为第二列比第0列小,其他列同理。

其实上面相当于是对19,54,10,44,30,42,41进行排序,带下划线的元素是主关键字,主关键字来自a(最后一行 ),当主关键字比较不出结果,则参考次关键字(b对应行)的比较结果得出最后的排序结果

另外对有序数组中,我们可以用searchsorted找到某个元素合适的位置。这里不一定会找到查找成功,但是如果待查找元素存在则一定在那个的位置上。因此searchsorted方法可以轻松找到某一个区间的临界点的索引。(注意如果元素存在且不止一个,则默认返回最左边的索引)

结构化和记录式数组

ndarray是一种同质的数据容器,所以在他表示的内存块中,各元素占用字节相同(取决于dtype)。但是我们可以通过设定更复杂的dtype使得数组能存储更多样的数据。这类似C语言中的结构体,以下是一个例子。

这是一个二维数组,第一列数据为浮点型,第二列数据为整型。并且可以用'x'来索引第一列。

在定义结构化dtype时,我们还可以设置一个形状(整数或者元祖)

如上例,各个记录的x字段所表示的是一个长度为3的数组。访问字段x即可访问到二维数组。

我们还可以通过嵌套来实现更复杂的结构化数组

ndarray每个元素在内存中被解释为固定的字节数,所以在ndarray的取址速度非常快(计算地址的速度更快了),因而使用结构体数组能够提供非常快速高效的磁盘数据读写速度。

用于数组的文件输入输出

np.loadnp.save是读写磁盘数据的两个主要函数,默认情况下,数组以未压缩的原始二进制格式保存在扩展名为.npy的文件中。使用savez可以将多个数组保存在同一个压缩文件中,如

np.savez('xxx.npz,a = arr1,b = arr2 )

在加载上述文件时,会得到类似字典的对象,通过关键字可以访问到对应的数组。

性能建议

将Python循环和条件逻辑转化转换为数组运算和布尔数组运算

尽量使用广播

避免复制数据,尽量使用数组视图(切片)

利用ufunc及其各种方法

资料来源:

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

以及晚上各位大佬的博文

AI遇见机器学习

mltoai

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180117G10I4U00?refer=cp_1026

同媒体快讯

相关快讯

扫码关注云+社区