“横看成岭侧成峰,远近高低各不同。Numpy渐欲迷人眼,浅草刚能没马蹄。”古人为了描述Numpy中Array的变幻莫测和难以掌控,曾留下千古名句,为后世传颂。阅读理解题:本诗前两句描述的是Array中的哪种操作?答案:切片。(看完男默女泪……气氛渐渐凝固 ( ̄▽ ̄")
不扯没用的了,下面我们来学习一些硬知识。有了上篇做铺垫,相信下篇学起来一定会如鱼得水,酣畅淋漓,欲罢不能!
02
多维数组
上篇提到的例子都是一维数组,其实Numpy可以创建任意维度的数组,所有之前提到的方法也可以应用在多维数组上。例如:一个列表的列表可以用来初始化一个二维数组:
通过二维数组我们已经发现了Array的强大(确定不是自嗨?):一个嵌套的List可以通过多次使用[ ]运算符来做索引访问元素,而多维数组支持一种更加自然的索引方法,即只用一个[ ]及多个用逗号隔开的标号来访问元素:
事实上,数组的形状可以随时改变,只要元素的总数不变就行。例如:我们需要一个从0递增的2x4数组,可以这样初始化:
-
视图,而非拷贝
变形(reshape)操作和Numpy中的大部分其他操作类似,只是提供相同内存的不同视图:
这种浅拷贝行为使得向量化运算非常高效。如果需要深拷贝,可按下面操作:
-
切片
对于多维数组,我们也可以使用切片,并可把切片和单个索引值混合使用(分别用在不同维度上),仍以上面的arr2为例:
如果只用一个索引值,则会返回低一维的数组,包含索引值所指的那一行:
-
数组的属性和方法
我们已经学会了如何创建多维数组,现在来了解一下数组的常用属性和方法。下面这些属性提供数组的大小、形状、数据类型等基本信息:
数组也有很多有用的方法,下面列出一些特别有用的:
上面的方法都是针对数组所有元素来做运算的,而对于多维数组,我们也可通过传入axis参数,实现只在某一维度上进行计算:
从上例可以看出,axis参数值代表运算进行时所消耗的那个维度值。这就是为什么在行方向上求和时需要设定axis=0。
Array的另一个常用属性是.T,可以返回该数组(或矩阵)的转置:
-
数组运算
数组支持所有常规的数学运算,numpy库中包含一整套可作用于数组上的基本数学函数。需要记住的是,所有面向数组的运算都是按元素进行的(Element-wise),即对数组中的所有元素同时生效。例如:
另外还需记住,数组的乘法运算也是按元素进行的,而不像线性代数中的矩阵乘法运算那样。
也可以乘以一个标量:
下面是一个“广播”的例子:
视觉化理解“广播”
这种为迁就对方而变形的行为实在太默契了,竟然让群主眼眶湿润 (☆▽☆)y
-
Element-wise函数
前面我们提到,numpy提供一整套作用于array上的数学函数,包括对数、指数、三角函数等。例如,在正弦函数上[0,2*pi]区间内均匀取100个样本点,可以用下面方法轻松实现:
-
Numpy中的线性代数运算
Numpy提供一套基本的线性代数函数库,如所有数组都可以应用dot方法,当参数为两个向量(一维数组)时,进行的是向量的标量积运算;当参数中至少有一个为二维数组时,进行的是传统的矩阵乘法运算。
下面是一个常见的矩阵向量乘法例子,注意数组v1应被看作一个列向量。Numpy并不区分行向量和列向量,只是简单地校验维度是否符合矩阵乘法运算规则。在下例中,我们用一个2x3的矩阵和一个3维向量相乘,得到一个2维向量:
对于矩阵乘法,相同的维度匹配规则也要被满足。考虑A×A.T和A.T×A的区别:
这节课的学习笔记好长,差点把群主整残了(ㄒoㄒ)/
Anyway,结果是最重要的,终于陪大家钻过了第一个火圈,倍感欣慰:)
下一周讲Pandas入门。人生若只如初见,何事秋风悲画扇,让我们休整一下疲惫的心,以对待初恋的心态迎接下一个、下下一个关卡吧!