这两天读完《利用Python进行数据分析》 这本书的第4章:NumPy 基础:数组和矢量计算 后,在进行下一步阅读高级应用前,先整理本章内容,做个笔记备查,也好加深印象。在往下看前请确保你已经安装了NumPy 库,并且已经使用 import numpy as np
加载numpy库。如果 还没有安装,那么可以在cmd(windows下)中使用 pip install numpy
命令安装,ubuntu下也可以使用 sudo apt-get install python-numpy
命令安装。
题外话:python的数据格式让我这种熟练了matlab的用户感觉好不习惯。>_<|||
np.array
来创建数组(ndarray),每个数组都有shape
属性和dtype
属性,shape
表示数组维数,dtype
表示数组元素类型。
astype
方法转换数组的dtype
,这个方法不会对原数组进行改动,会创建一个新的数组,也就是说原数组还是原来的dtype
np.zeros(), np.ones(), np.eye(), np.empty()
创建特殊数组,这一点和matlab还是差不多的,不过需要注意的是,如果你要创建一个2*3的全零数组,那么就应该这么写:np.zeros((2, 3))
,也就是说传入的是一个元祖,如果你熟悉matlab你可能就会直接写np.zeros(2, 3)
,这在python中是不正确的。此外,在用np.empty()
创建空数组时,实际上返回的并不是空数组,而是一些未初始化的垃圾值。np.arange()
是一个很有用的函数,返回给定范围内的连续值,注意下标从0开始,不包括末尾值。
如果不想要这样的效果,想要一个独立的新数组,那么需要使用显示复制函数,例如arr_independent = arr[5:8].copy()
。
对于多维数组的索引,需要注意的是有一个“轴”的问题(matlab用户肯定很奇怪),其实就是行和列,下面有个图说明。
再用个例子来说明下高维数组的索引方式。
除此之外还有一个布尔型索引,这个和matlab是一样的。
如果传入的是一个元组,那么假设用i
表示第j
(从0开始)个位置的数值,那么转置之后的数组的第j
个轴就是原数组的第i
个轴(不得不吐槽这什么玩意儿,太别扭了),下面用一个例子来说明,
这里原始数组是一个2×2×4的三维数组,transpose
的参数是元组(1, 0, 2),对应的下标索引为(0, 1, 2),对比可以知道,arr.transpose(1, 0, 2)
的意思就是将原数组 arr 的(0, 1)位置和(1, 0)位置互换,以此类推。
where
函数
numpy.where
函数是三元表达式x if condition else y
的矢量化版本。
其实和 Java 中的问号表达式也是异曲同工。这种用法很多时候真的很方便(废话),比如图像处理中我想把像素矩阵中大于110的全都置为1,小于110的都置为0,那么就可以这么写np.where(matrix > 110, 1, 0)
。 同样用随机数举一个例子,
====== 2016-06-27更新 ======
numpy.where
函数在求一个数组最大值/最小值所在位置的时候也很有用,例如:
其中另一种方法求最大值所在位置使用了numpy.argmax
函数,该函数可直接返回最大值位置(啰嗦了~~)。
主要就是计算均值、方差、求和、最大值、最小值、累计和和累计积等。
需要注意的:假设有一个 5×4 的二维数组 arr ,那么np.mean(arr)
表示对整个二维数组的平均,即全部加起来除以个数,并不是matlab中的默认对列求平均。如果想要得到对某个轴向求平均,可以加上axis
参数,如np.mean(arr, 1)
就是对行求平均。其他函数类似。
基本数组统计方法
===== 2016-06-29更新 =====
注意,numpy.std()
求标准差的时候默认是除以 n
的,即是有偏的,而pandas.std()
默认是除以n-1
的,即是无偏的,如果想和numpy.std()
一样有偏,需要加上参数ddof=0
,即pandas.std(ddof=0)
。
*
,使用 *
得到的结果等于是matlab中使用点乘.*
的结果,使用dot函数才是真正的矩阵乘法。from numpy.linalg import inv, qr
等等,以此类推。这里着重说一下randn
和normal
。 书上在使用randn
的时候都是直接使用,但是我自己输入的时候却必须要这样np.random.randn
。 此外,randn
默认只能生成标准正太分布的随机数,想要使用randn
来生成非标态分布的随机数,那么可以这么写:sigma * np.random.randn(size) + mu
。但是使用normal就可以轻松的生成各种正态分布的随机数:normal(loc=0.0, scale=1.0,size=None)
,loc是均值,scale是标准差。
randint
是从给定的范围内随机选取整数,注意是闭区间。
部分numpy.random函数
NumPy很多地方都是借鉴matlab的,所以说有很多相似之处,也有一些不同之处,可以参考下面的对照表,表格来自Numpy for Matlab users
关于数组的集合运算以及我的一些测试(太懒就不写了,直接拍我记在书上的。。),就是setdiff1d(x, y)
和setxor1d(x, y)
的一些细微差别,后者对于x和y的顺序貌似不感冒,如有错,欢迎指正!
断断续续写了快一天,我真是服了,whatever,its done!
See you~