NumPy基本应用学习
NumPy模块为量化金融提供了大量的数据编程工具,可以方便的处理向量、矩阵等运算,极大便利人们在科学计算方面的工具。
一、如何使用NumPy
在python中使用简单的导入命令即可使用
import numpy
numpy.version.full_version
'1.19.2'
二、NumPy对象初步:数组
Numpy的基本对象是同类型的多维数组,看例子:
import numpy as np
a=np.arange(20)
此处就生成了一个一维数组a,从0开始,步长为默认值1,长度为20.
print(a)
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
我们使用type来查询a的类型,这里显示a是一个数组
type(a)
numpy.ndarray
通过函数reshape()可以重塑这个数组,例如可以生成一个4X5的二维数组,reshape函数中的参数,表示各维数的大小,分别对应行数和列数。
b=a.reshape(4,5)
print(b)
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
还可以构建更高维数的数组
c=a.reshape(2,2,5)
print(c)
[[[ 0 1 2 3 4]
[ 5 6 7 8 9]]
[[10 11 12 13 14]
[15 16 17 18 19]]]
由于a是数组(array),那么可以调用array的函数来查看a的相关属性,ndim可以查询维度,shape可以查询各个维度的大小,size可以查看数组中元素的个数,dtype可以查看元素类型,dsize可查看元素占存储空间的大小(以字节为单位)。
c.ndim
3
c.shape
(2, 2, 5)
c.size
20
c.dtype
dtype('int32')
三、创建数组
数组的创建可以从将列表转换开始,高维数组可通过转换嵌套列表实现。
rraw=[0,1,2,3,4]
a=np.array(rraw)
a
array([0, 1, 2, 3, 4])
raw=[[0,1,2,3,4],[5,6,7,8,9]]
b=np.array(raw)
b
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
一些特殊的数组由特殊的命令生成,例如创建4X5的全零矩阵:
d=(4,5)
np.zeros(d)
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
这里默认生成的元素都是浮点型,可以通过指定类型来改变。例如
d=(4,5)
np.ones(d,dtype=int)
array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
还可以创建一个随机数组
R=np.random.rand(5)
print(R)
[0.65478038 0.60866488 0.14315106 0.13627398 0.2908694 ]
四、数组和矩阵的运算
数组的四则运算是对全部的数组元素的运算,例如
a=np.array([[1,2],[2,4]])
b=np.array([[3,5],[5,6]])
print(a+b)
[[ 4 7]
[ 7 10]]
print(3*a)
[[ 3 6]
[ 6 12]]
a/2
array([[0.5, 1. ],
[1. , 2. ]])
np.exp(a)
array([[ 2.71828183, 7.3890561 ],
[ 7.3890561 , 54.59815003]])
np.sqrt(a)
array([[1. , 1.41421356],
[1.41421356, 2. ]])
np.power(a,3)
array([[ 1, 8],
[ 8, 64]], dtype=int32)
NumPy提供了矩阵对象(Matrix)。矩阵对象和数组对象的主要区别是,矩阵是二维的,数组可以是任意维数的;矩阵的“*”操作符进行的是矩阵的乘法,而数组的乘法操作符是对应的元素两两相乘。数组可以转换到矩阵。
a=np.arange(20).reshape(4,5)
a=np.asmatrix(a)
b=np.matrix('1.0 2.0;3.0 4.0')
print(type(b))
<class 'numpy.matrix'>
五、访问数组和矩阵元素
数组和矩阵元素的访问方式可以通过下标索引来进行,以二维数组(或者矩阵为例)。
import numpy as np
a=np.array([[3.2,2.5],[2.5,4]])
print(a[0][1])
2.5
b=a
a[0][1]=2.0
print(b)
[[3.2 2. ]
[2.5 4. ]]
print(a)
[[3.2 2. ]
[2.5 4. ]]
注意此处,当a的元素改变的时候,b里面的元素值也改变了,这是因为这里并不是真正将a的值赋给b,而是将b设置为指向a对应数据内存的地址。要想真正将a复制给b,可以使用copy函数。
b=a.copy()
a[0][1]=3
print(a)
[[3.2 3. ]
[2.5 4. ]]
print(b)
[[3.2 2. ]
[2.5 4. ]]
如果再对a重新赋值,则会将a指向其他地址,但是b仍然是原来的地址。
a=np.array([[3.2,1.5],[2.5,4]])
b=a
a=np.array([[2,1],[9,3]])
print(a)
[[2 1]
[9 3]]
print(b)
[[3.2 1.5]
[2.5 4. ]]
复杂的矩阵(数组)的操作,下面的例子是将a中第一列大于5的元素(10和15)对应的第三列元素(12和17)取出来
a=np.arange(20).reshape(4,5)
print(a)
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
a[:,2][a[:,0]>5]
array([12, 17])
可以使用where函数查找特定值在数组中的位置
loc=np.where(a==11)
print(loc)
(array([2], dtype=int64), array([1], dtype=int64))
print(a[loc[0][0],loc[1][0]])
11
六、矩阵操作
1)矩阵的转置
a=np.random.rand(2,4)
print(a)
[[0.5313874 0.07565913 0.1075944 0.02040496]
[0.37247355 0.08133408 0.31588994 0.04461943]]
a=np.transpose(a)
print(a)
[[0.5313874 0.37247355]
[0.07565913 0.08133408]
[0.1075944 0.31588994]
[0.02040496 0.04461943]]
b=np.random.rand(2,4)
b=np.mat(b)
print(b.T)
[[0.77892814 0.02886124]
[0.1553499 0.40015598]
[0.18063926 0.97742789]
[0.5086811 0.19250614]]
2)求矩阵的逆
import numpy.linalg as nlg
a=np.random.rand(2,2)
a=np.mat(a)
ia=nlg.inv(a)
print(ia)
[[-3.13919005 4.47161099]
[ 8.83634098 -7.46197266]]
print(a*ia)
[[ 1.00000000e+00 -5.07742246e-16]
[ 3.60418327e-17 1.00000000e+00]]
3)求特征矩值和特征向量
a=np.random.rand(3,3)
eig_value,eig_vector=nlg.eig(a)
print(eig_value)
[ 1.5663706 -0.06426978 0.32476154]
print(eig_vector)
[[-0.56172522 -0.47816424 -0.19734601]
[-0.60224957 0.87812593 -0.67091569]
[-0.56723913 -0.01593141 0.71479136]]
4)矩阵的拼接,将两个向量拼接成矩阵
a=np.array((1,2,3))
b=np.array((2,3,4))
c=np.column_stack((a,b))
d=np.column_stack((b,a))
print(c)
[[1 2]
[2 3]
[3 4]]
print(d)
[[2 1]
[3 2]
[4 3]]
a=np.random.rand(2,2)
b=np.random.rand(2,2)
print(a)
[[0.10796419 0.14265679]
[0.13323965 0.96681789]]
print(b)
[[0.17852727 0.385924 ]
[0.59352195 0.31530558]]
c=np.hstack([a,b]) %水平拼接
d=np.vstack([a,b]) %垂直拼接
print(c)
[[0.10796419 0.14265679 0.17852727 0.385924 ]
[0.13323965 0.96681789 0.59352195 0.31530558]]
print(d)
[[0.10796419 0.14265679]
[0.13323965 0.96681789]
[0.17852727 0.385924 ]
[0.59352195 0.31530558]]
七、缺失值
缺失值在量化分析中也是一种信息,NumPy提供了nan作为缺失值记录,通过isnan函数判定是否为缺失值。
a=np.random.rand(2,2)
a[0,1]=np.nan
print(np.isnan(a))
[[False True]
[False False]]
nan_to_num函数可以将nan替换成0
print(np.nan_to_num(a))
[[0.03229265 0. ]
[0.97999597 0.71549986]]