python数据科学基础库主要是三剑客:numpy,pandas以及matplotlib,每个库都集成了大量的方法接口,配合使用功能强大。平时虽然一直在用,也看过很多教程,但纸上得来终觉浅,还是需要自己系统梳理总结才能印象深刻。本篇先从numpy开始,对numpy常用的方法进行思维导图式梳理,多数方法仅拉单列表,部分接口辅以解释说明及代码案例。
这部分内容比较基础,仅补充一个个人认为比较有用的ufunc加聚合的例子。ufunc本身属于方法(方法即是类内的函数接口),ufunc之上还支持4个方法:
当然,后两个用处较少也不易理解,前两个在有些场景下则比较有用:
02 数组创建
numpy中支持5类创建数组的方式:
从普通数据结构创建,如列表、元组等
从特定的array结构创建,支持大量方法,例如ones、zeros、empty等等
从磁盘读取特定的文件格式
从缓存或字符读入数组
从特定的库函数创建,例如random随机数包
以上方法中,最为常用的是方法1、2、5。
03 数组增删
numpy提供了与列表类似的增删操作,其中
三种方法需要接收一个axis参数,如果未指定,则均会先对目标数组展平至一维数组后再执行相应操作。
04 数组变形
数组变形是指对给定数组重新整合各维度大小的过程,numpy封装了4类基本的变形操作:转置、展平、尺寸重整和复制。主要方法接口如下:
resize与reshape功能类似,主要有3点区别:
另外,当resize新尺寸参数与原数组大小不一致时,要求操作对象具有原数组的,而不能是view或简单赋值。(具体参考08 视图与拷贝一节)
ravel和flat功能类似,均返回对数组执行展平后的结果,且不改变原数组形状,区别在于:
transpose与T均执行转置操作,前者是方法,后者是属性
tile和repeat方法类似,均为对给定数组执行复制操作,区别在于:
05 数组拼接
数组拼接也是常用操作之一,主要有3类接口:
stack系列,共6个方法:
魔法方法:r_[ ],c_[ ],效果分别与row_stack和column_stack类似,但具体语法要求略有不同。另外,虽然不是函数,但第一个参数可以是一个字符串实现特定功能设置。
06 数组切分
数组切分可以看做是数组拼接的逆操作,分别对应:
hsplit:水平切分,要求切分后大小相等,维数不变,可以切分一维数组
07 基本统计量
numpy可以很方便的实现基本统计量,而且每种方法均包括对象方法和类方法:
08 视图与拷贝
与列表的操作类似,numpy的数组类型也存在深浅拷贝之分:
注:正因为赋值和view操作后两个数组的数据共享,所以在前面resize试图更改数组形状时可以执行、但更改元素个数时会报错。
09 特殊常量
numpy提供了一些特殊的常量,值得注意的是np.newaxis可以用作是对数组执行升维操作,效果与设置为None一致。
10 随机数包
Random是numpy下的一个子包,内置了大量的随机数方法接口,包括绝大部分概率分布接口,常用的主要还是均匀分布和正态分布:
11 线性代数包
除了随机数包,numpy下的另一个常用包是线性代数包,常见的矩阵操作均位于此包下。由于点积dot()和向量点积vdot()操作使用较为频繁,所以全局可用。
12 关于axis的理解
由于numpy的基本数据结构是多维数组,很多接口方法均存在维度的问题,按照不同维度执行操作结果往往不同,例如拼接、拆分、聚合统计等,此时一般需要设置一个维度参数,即axis。由于很多教程因为翻译或语言习惯不同,存在众说纷纭、口径不一的问题,有的说axis=0是横轴,有的说是纵向,所以如何理解axis的含义可能是很多numpy初学者的常见困扰之一,笔者也是如此。
这一问题困扰了好久,直至一次无意间看到了相关源码中的注释:
如,在sort方法中,axis参数的解释为"Axis along which to sort",翻译过来就是沿着某一轴执行排序。这里的沿着一词用得恰到好处,形象的描述了参数axis的作用,即相关操作是如何与轴向建立联系的,在具体解释之前,先介绍下axis从小到大的顺序问题。axis从小到大对应轴的出场顺序先后,或者说变化快慢:axis=0对应主轴,沿着行变化的方向,可以理解为在多重for循环中最外面的一层,对应行坐标,数值变化最慢;而axis=1对应次轴,沿着列变化的方向,在多重for循环中变化要快于axis=0的轴向。类似地,如果有更高维度则依次递增。
至此,再来理解这里axis沿着的意义。举个例子,axis=0代表沿着行变化的方向,那么自然地,切分方法split(axis=0)接口对应vsplit,因为是对行切分,即垂直切分;而split(axis=1)接口则对应hsplit,因为是对列切分,即水平切分;split(axis=2)则对应dsplit。类似的,np.sort(axis=0)必然是沿着行方向排序,也就是分别对每一列执行排序。
想必这样理解,应该不会存在混淆了。
13 关于广播机制
可能困扰numpy初学者的另一个用法是numpy的一大利器:广播机制。广播机制是指执行ufunc方法(即对应位置元素1对1执行标量运算)时,可以确保在数组间形状不完全相同时也可以自动的通过广播机制扩散到相同形状,进而执行相应的ufunc方法。
当然,这里的广播机制是有条件的:
条件很简单,即从两个数组的最后维度开始比较,如果该维度满足维度相等或者其中一个大小为1,则可以实现广播。当然,维度相等时相当于未广播,所以严格的说广播仅适用于某一维度从1广播到N;如果当前维度满足广播要求,则同时前移一个维度继续比较。
为了直观理解这个广播条件,举个例子,下面的情况均满足广播条件:
而如下例子则无法完成广播: