1. numpy多维数组的理解
关于多维数组比较抽象,特别是非图形化的,而是存储在内存中的形式。关于numpy多维数组的简单理解,先看下图:
不像matlab,numpy是行优先存储的,所以numpy数组的最后一个维度永远是列,这些元素基本上总是在内存中是连续的。
一维是一个列表,那么二维就是列表的列表,所以上图2维理解就是最外面的列表有两个列表,然后每个内部列表有四个对象。
对于三维来说,每个列表有两个两行列表,每个列表就是二维的理解,即列表的列表的列表。
2.numpy的创建函数
1)np.array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0),可以把python列表、元组等结构转为numpy数组。
2)np.arange([start,] stop[, step,], dtype=None) ,这个参数类似python range
3)np.ones(shape, dtype='float64') , 注意传入参数是shape,默认类型是float64,可以dtype来指定。
np.zeros(shape,dtype='float64')
4)np.identity(n, dtype=None), 就是矩阵中的单位矩阵
5)np.empty(shape, dtype=float, order='C'), 返回一个未经初始化的矩阵,即返回的矩阵只是shape为指定形式,但是值都是随机的。
6)np.linespace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0),返回一个均分的数组,前三个参数指定起止数和间隔, endpoint参数指的是stop的参数是不是最后一个数据,retstep参数设定是否要返回间隔值。例子如下:
3. numpy的计算规则和方法
1)numpy数组的计算参考下面四条规则
- 多维数组之间进行运算首先检查shape是否匹配。
- 数学运算符(+-*/exp,log等)是作用于每个元素的
- sum、mean、max、std等reduction操作是作用于整个数组的,除非指定axis参数
- 如果数组中有nan值参与运算,则结果都为nan,如果非要计算可以采用nanmean、nansum等nan系列函数
上面几条规则看起来我们一条一条来分析。
第1条:多维数组之间运算先检查shape,这个很容易理解,两个shape为(3,2)的数组可以直接相加,但是看下面的例子:
上面例子中a的shape是(3,4),而b的shape是(4,),但是他们之间能够进行+运算,这个特性就是numpy的Broadcasting特性。
其实最简单的Broadcasting特性应用是numpy数组跟一个常量进行运算时,我们前面见过例 a + 4。我们可以想象在a与b进行运算时,b按照原始数据进行拷贝拓展为与a同样shape的数组,这样再与a进行运算,但是实际上numpy并没有额外进行拷贝等操作,它是利用c的for循环实现的,所以这种特性是不影响效率的与内存消耗的。
有两张图有助于理解。
关于这种特性的详细介绍,可以参考:https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
介绍的是很详细了,这里就不展开讨论了。
第2条:这条好理解,不做赘述。
第3条:这一条很重要的一点是关于axis的说明。对于多维数组我们经常需要只计算某一维度的数据,这时候就需要用到axis参数了。这个参数很多文档介绍都是axis=0代表行,axis=1代表列,这种记法极易出错,而且对于多维数组有时候很难判断。
看到一种比较好的理解方式是,axis代表的就是下图展示的维度数值,那axis等于哪个维度,哪个维度(或者称为轴)就会消失,形象理解就是这个维度被压缩。举个例子a的shape为(3,1,5,2),那么a.sum(axis=3)返回的shape就为(3,1,2),这个就比较容易判断我们所选择的axis到底是不是正确。再拿二维举例,a的shape为(3,2),那么axis=0时,返回的shape就是(2,),axis=1的时候返回的shape即为(3,),是不是很容易。
第4条:这一条举几个例子看一下就明白了,总之nan是一个特别的东西,像黑洞似的。
2) numpy的一些常见函数:
min、max、mean、sum、std等就不介绍了,字面意思记忆即可。
np.argmax、np.argmin(a, axis=None, out=None): 返回指定轴最大、最小值的索引。
np.where
np.unravel_index
上面函数及其他常用函数用法,参考https://docs.scipy.org/doc/numpy/reference/
介绍的很详细,例子很很棒。
关于numpy的两天学习,个人觉得还是得多练习,才能熟练的组织出自己想要的数据,对于numpy的花式索引、broadcasting等特性需要更多的实践来理解。