Numpy系列目录
NumPy 提供了线性代数和多项式函数库。包含了线性代数中行列式、向量、矩阵,相关常用操作以及解方程和多项式的功能。
np.matmul(x1, x2)
:两个矩阵的乘积。x1的行数需和x2的列数相同。@
运算符:x1 @ x2表示两个矩阵乘法。其中一个数据为一维数组时,第一个参数默认被认为是行向量,后一个参数默认被认为是列向量。
>>> a=np.array([1,2,3])
>>> np.inner(a,a) #向量点乘
14
>>> b=np.array([[1,1,1],[2,2,2]])
>>> np.inner(a,b) #多维数组中每个向量与向量做点乘
array([ 6, 12])
>>> a=np.array([[1,2,3],[3,3,3]])
>>> np.inner(a,b) #沿最后一维求内乘
array([[ 6, 12],
[ 9, 18]])
>>> a=np.array([1,2,3])
>>> np.outer(a, a)
array([[1, 2, 3],
[2, 4, 6],
[3, 6, 9]])
[ x 1 , x 2 , . . . ] [x_1,x_2,...] [x1,x2,...]与 [ y 1 , y 2 , . . . ] [y_1,y_2,...] [y1,y2,...]的内积为 ∑ x i y i \sum x_i y_i ∑xiyi。
[ x 1 , x 2 , . . . ] [x_1,x_2,...] [x1,x2,...]与 [ y 1 , y 2 , . . . ] [y_1,y_2,...] [y1,y2,...]的外积为
[ x 1 ∗ y 1 x 2 ∗ y 1 x 3 ∗ y 1 x 1 ∗ y 2 x 2 ∗ y 2 x 3 ∗ y 2 x 1 ∗ y 3 x 2 ∗ y 3 x 3 ∗ y 3 ] \left[\begin{array}{ccc} x_1*y_1 & x_2*y_1 & x_3*y_1 \\ x_1*y_2 & x_2*y_2 & x_3*y_2 \\ x_1*y_3 & x_2*y_3 & x_3*y_3 \end{array}\right] ⎣⎡x1∗y1x1∗y2x1∗y3x2∗y1x2∗y2x2∗y3x3∗y1x3∗y2x3∗y3⎦⎤
通常我们认为点积就是内积,但是在函数库里,点积积dot运算和内积有一定不同。
>>> a=np.array([1,2,3])
>>> np.dot(a,a)
14
>>> np.dot(b,a)
array([ 6, 12])
>>> b=np.array([[1,2],
... [1,2],
... [1,2]])
>>> np.dot(a,b)
array([[ 6, 12],
[ 9, 18]])
>>> a=np.array([1,2,3])
>>> b=np.array([[1,2],[3,4]])
>>> np.vdot(a,a)
14
>>> np.vdot(b,b)
30
np.tensordot(a,b)
:张量缩并,也称张量缩约,即把a,b的-1,-2维度进行内积运算,缩减2个维度。np.tensordot(a,b,(0,1))
:沿a的0维,b的1维方向点积运算np.tensordot(a,b,([0,1],[0,1]))
:a的0维和1维展开为向量,b的0维度和1为展开为向量,做点积张量缩并(缩约):
两个数组最后的2个维度展开为向量后内积,从而使维度减2。a为M维,b为N维,则输出为max(M,N)-2维。
所以缩并的两个数组都必须不小于2维。
张量缩约
>>> a=np.arange(9).reshape(3,3)
>>> np.tensordot(a,a)
array(204)
>>> b=np.arange(27).reshape(3,3,3)
>>> np.tensordot(a,b)
array([612, 648, 684])
张量沿指定轴做点积
>>> a=np.array([[1,2],[1,2]])
>>> np.tensordot(a,a,(1,1))
array([[5, 5],
[5, 5]])
>>> np.tensordot(a,a,((0,1),(0,1)))
array(10)
>>> a
array([1, 2, 3])
>>> np.cross(a,a)
array([0, 0, 0])
a,b中存在多维数组时,通过广播,对对应的向量进行叉乘计算。
Kronecker积是两个任意大小的矩阵间的运算,表示为⊗,又称为直积或张量积。
A = [ x 1 1 x 1 2 x 2 1 x 2 2 ] B = [ y 1 1 y 1 2 y 2 1 y 2 2 ] A ⊗ B = [ x 1 1 ∗ y 1 1 x 1 1 ∗ y 1 2 x 1 1 ∗ y 2 1 x 1 1 ∗ y 2 2 x 1 2 ∗ y 1 1 x 1 2 ∗ y 1 2 x 1 2 ∗ y 2 1 x 1 2 ∗ y 2 2 x 2 1 ∗ y 1 1 x 2 1 ∗ y 1 2 x 2 1 ∗ y 2 1 x 2 1 ∗ y 2 2 x 2 2 ∗ y 1 1 x 2 2 ∗ y 1 2 x 2 2 ∗ y 2 1 x 2 2 ∗ y 2 2 ] A=\left[\begin{array}{cc} x_11 & x_12 \\ x_21 & x_22 \end{array}\right] B=\left[\begin{array}{cc} y_11 & y_12 \\ y_21 & y_22 \end{array}\right] A \otimes B=\left[\begin{array}{cccc} x_11 *y_11 & x_11*y_12 & x_11*y_21 & x_11*y_22 \\ x_12 *y_11 & x_12*y_12 & x_12*y_21 & x_12*y_22 \\ x_21 *y_11 & x_21*y_12 & x_21*y_21 & x_21*y_22 \\ x_22*y_11 & x_22*y_12 & x_22*y_21 & x_22*y_22 \end{array}\right] A=[x11x21x12x22]B=[y11y21y12y22]A⊗B=⎣⎢⎢⎡x11∗y11x12∗y11x21∗y11x22∗y11x11∗y12x12∗y12x21∗y12x22∗y12x11∗y21x12∗y21x21∗y21x22∗y21x11∗y22x12∗y22x21∗y22x22∗y22⎦⎥⎥⎤
np.kron(a,b)
:求a,b的张量积。a形状为(M,N),b形状为(J,K),则结果为(M×J,N×K)>>> a=np.array([[1,2],[1,2]])
>>> b=np.array([3,4])
>>> np.kron(a,b)
array([[3, 4, 6, 8],
[3, 4, 6, 8]])
对正定方阵A,可以分解为三角方阵L与L.T(L的转置)的矩阵乘积。
>>> a
array([[ 1, 3, 5],
[ 3, 13, 17],
[ 5, 17, 42]])
>>> np.linalg.cholesky(a)
array([[1., 0., 0.],
[3., 2., 0.],
[5., 1., 4.]])
>>> np.dot(_,_.T) #np.matmul(_,_.T)
array([[ 1., 3., 5.],
[ 3., 13., 17.],
[ 5., 17., 42.]])
判别对称矩阵A的正定性有两种方法:
- A的所有特征值均为正数,则A是正定的。
- A的各阶主子式均大于零,则A是正定的。
对于半正定矩阵
[[1,2],[1,2]]
不出错,但是分解出来的结果也不太准。
M×N的矩阵,M≥N可以分解为:M×M正交矩阵与非奇异上三角矩阵R(M×N)的乘积。
>>> a
array([[ 0, 3, 1],
[ 0, 4, -2],
[ 2, 1, 2]])
>>> q,r=np.linalg.qr(a)
>>> q
array([[ 0. , -0.6, -0.8],
[-0. , -0.8, 0.6],
[-1. , 0. , 0. ]])
>>> r
array([[-2., -1., -2.],
[ 0., -5., 1.],
[ 0., 0., -2.]])
>>> np.dot(q,r)
array([[ 0., 3., 1.],
[ 0., 4., -2.],
[ 2., 1., 2.]])
当M>N时r的最后几行均为0。
正交矩阵指,矩阵的转置和矩阵的逆相等
M×N矩阵被分解为, U S V ∗ USV^* USV∗。U为M×M正交矩阵,V的共轭转置为N×N正交矩阵,R(M×N)的乘积。
S为的M×N对角矩阵(主对角线以外都为0),称为奇异值。
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> u,s,vt=np.linalg.svd(a) #奇异值分解
>>> u
array([[-0.1473065 , -0.90090739, 0.40824829],
[-0.50027528, -0.2881978 , -0.81649658],
[-0.85324407, 0.32451178, 0.40824829]])
>>> s
array([2.24092982e+01, 1.95534034e+00, 7.68985043e-16])
>>> v
array([[-0.39390139, -0.46087474, -0.5278481 , -0.59482145],
[ 0.73813393, 0.29596363, -0.14620666, -0.58837696],
[-0.50775138, 0.52390687, 0.47544042, -0.4915959 ],
[-0.20539847, 0.65232016, -0.68844492, 0.24152322]])
>>> smat = np.append(np.diag(s),np.zeros((3,1)),axis=1) #恢复m×n对角阵
>>> smat
array([[2.24092982e+01, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.95534034e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 7.68985043e-16, 0.00000000e+00]])
>>> (u @ smat @ vt).round(2) #核对u,s,vt乘积
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
注意np.linalg.svd得到的奇异值为向量。
对于n阶方阵A,如果存在数 λ \lambda λ和非零列向量X,使得
A X = λ X AX=\lambda X AX=λX
则数λ称为矩阵A特征值,非零向量X称为A的对应于特征值λ的特征向量。
es[i]
为第i个特征值vs[:,i]
vs的第i列,为第i个特征值对应的特征向量>>> a=np.array([[2,3],[2,1]])
>>> es,vs=np.linalg.eig(a)
>>> es
array([ 4., -1.])
>>> vs
array([[ 0.83205029, -0.70710678],
[ 0.5547002 , 0.70710678]])
>>>
>>> a@vs[:,0]
array([3.32820118, 2.21880078])
>>> es[0]*vs[:,0]
array([3.32820118, 2.21880078])
>>>
>>> a@vs[:,1]
array([ 0.70710678, -0.70710678])
>>> es[1]*vs[:,1]
array([ 0.70710678, -0.70710678])
A X = λ X AX=\lambda X AX=λX,也可以写成 ( A − λ I ) X = 0 (A-\lambda I)X=0 (A−λI)X=0。这是n个未知数n个方程的齐次线性方程组,它有非零解的充分必要条件是系数行列式|A-λE|=0
厄米特矩阵(Hermitian)是指其共轭转置等于自身的矩阵,对于实数矩阵,厄米特矩阵就是对称矩阵。
典型的厄尔米特矩阵:
[ 1 2 + 2 j 3 − 3 j 2 − 2 j 2 − j 3 + 3 j j 5 + j ] \left[\begin{array}{ccc} 1 & 2+2j & 3-3j \\ 2-2j & 2 & -j \\ 3+3j & j & 5+j \end{array}\right] ⎣⎡12−2j3+3j2+2j2j3−3j−j5+j⎦⎤
Hermitian矩阵也可以用np.linalg.eig(a)求特征值和特征向量。numpy还提供了一个专用的计算函数
np.linalg.eigh,用法与np.linalg.eig相同。
es[i]
为第i个特征值vs[:,i]
vs的第i列,为第i个特征值对应的特征向量>>> a
array([[1, 0, 0],
[0, 2, 0],
[0, 0, 3]])
>>> es,vs=np.linalg.eigh(a) #计算特征值和特征向量
>>> a @ vs[:,0] #a和第一个特征向量乘积
array([1., 0., 0.])
>>> es[0] * vs[:,0] #第一个特征值和第一个特征向量乘积
array([1., 0., 0.])
>>>
>>> a @ vs[:,1] #a和第二个特征向量乘积
array([0., 2., 0.])
>>> es[1] * vs[:,1] #第二个特征值和第二个特征向量乘积
array([0., 2., 0.])
np.linalg.eigh不能用于求非Hermitian矩阵,比如:
[[2,3],[2,1]]
可以用eig求解,用eigh结果就不对,
>>> a
array([[2, 3],
[2, 1]])
>>> np.linalg.eigvals(a)
array([ 4., -1.])
np.diag(a)
:a是矩阵,则返回对角线元素向量。a是向量则返回对角矩阵np.tri(N,M=None,k=0)
:创建N行M列下三角矩阵,k为偏移量。不指定M则创建方阵。np.tril(a,k=0)
:对矩阵a,上三角填充0,k为偏移量np.triu(a,k=0)
:对矩阵a,下三角填充0,k为偏移量np.trace(a)
:求矩阵的迹,即对角线之和np.linalg.det(a)
:求a的行列式。a为维度超过2时,最后两维必须为方阵矩阵和向量的范数都是大于等于0的数值。
条件数指a的范数与a的逆的范数的乘积。
np.linalg.cond(a,order=None)
:计算a的条件数。a可以为矩阵或向量。np.linalg.matrix_rank(a)
:使用SVD方法返回数组的矩阵的ranknp.linalg.inv(a)
:计算方阵的逆,只有满秩矩阵可逆非方阵或者非满秩矩阵无法计算逆矩阵。对于矩阵A,可以求其伪逆矩阵B,B满足:
ABAA,BABB。B形状与A的转置形状相同
B=np.linalg.pinv(A)
:计算非方阵或者非满秩矩阵的伪逆矩阵。求解线性方程组
x=np.linalg.solve(A,B)
:求Ax=b的解
最小二乘求线性方程系数
已知x,y两个向量,组成的若干个点(xi,yi)。拟合方程y=wx+b
Cannot read properties of undefined (reading 'type')
用A表示上式中最左侧[x,1]
形式的矩阵,z表示系数向量[w,b]
,则上式变为Az=y。
最小二乘法求[w,b]
方式入下:
w,b = np.linalg.lstsq(A,y)
:求解线性方程系数用
A = np.vstack([x, np.ones(len(x))]).T
可以得到系数矩阵A
求解线性方程组
x=np.linalg.solve(a,b)
:求解线性方程组ax=b的根。>>> a = np.array([[1, 2], [3, 5]])
>>> b = np.array([1, 2])
>>> x = np.linalg.solve(a, b)
>>> x
array([-1., 1.])
numpy多项式有两个api:
p=np.poly1d([1,2,3])
:创建多项式类对象,多项式为1x**2+2x+3
p(0.5)
:求解x=0.5时多项式的值p.r
:or p.roots,求多项式等于0的方程的根x**2+2x+3=5
的根np.polyval([1,2,3],5)
:求x**2+2x+3=5
的根最小二乘法拟合
np.polyfit(x,y,deg)
:根据(x,y)数据点,拟合deg阶多项式p=np.polynomial.Polynomial([1,2,3])
:创建1+2x+3x**2
多项式。注意和poly1d相反p=np.polynomial.Chebyshev([1,2,3])
:创建T0(x)+2T1(x)+3T2(x)切比雪夫多项式p=np.polynomail.Hermite([1,2,3])
:创建H0(x)+2H1(x)+3H2(x)埃尔米特物理学多项式p=np.polynomail.HermiteE([1,2,3])
:创建He0(x)+2He1(x)+3He2(x)埃尔米特概率学多项式p=np.polynomail.Laguerre([1,2,3])
:创建L0(x)+2L1(x)+3L2(x)拉盖尔多项式p=np.polynomail.Legendre([1,2,3])
:创建P0(x)+2P1(x)+3P2(x)勒让德多项式p.fromroots()
:根据多项式等于0方程的根r,创建(x-r[0])*(x-r[1])*...*(x-r[n-1])
多项式对象p1+p2, np.polynomial.polynomial.polyadd(p1,p2)
:多项式和多项式或常数相加p1-p2, np.polynomial.polynomial.polysub(p1,p2)
:多项式和多项式或常数相减p1*p2, np.polynomial.polynomial.polymul(p1,p2)
:多项式和多项式或常数相乘p1**n, np.polynomial.polynomial.polypow(p1,n)
:多项式的n次方,n必须为正整数np.polynomial.polynomial.polymulx([1,2,3])
:多项式乘以x,参数不能为多项式对象np.polynomial.polynomial.polydiv(p1,p2)
:多项式和多项式或常数除
Numpy系列目录
个人总结,部分内容进行了简单的处理和归纳,如有谬误,希望大家指出,持续修订更新中。
修订历史版本见:https://github.com/hustlei/AI_Learning_MindMap
未经允许请勿转载。