Numpy有很多矩阵运算的方法,小白总结了一些常用和认为在算法中用到的方法~
基础操作:
首先创建两个矩阵
A = np.array([[1,2],[1,2]])
B = np.array([[2,4],[5,5]])
1.矩阵对应位置的元素相加
#矩阵同位置元素相加
np.add(A,B)#方法1
A+B #方法2
结果都为:
array([[3, 6],
[6, 7]])
2.矩阵对应位置的元素相乘
#矩阵对应位置的每个元素相乘
A*B
结果为:
array([[ 2, 8],
[ 5, 10]])
与之对应的就有矩阵相乘的运算
#矩阵相乘
A.dot(B) #方法1
np.dot(A,B)#方法2
结果为:
array([[12, 14],
[12, 14]])
进阶操作:
用之前博文中介绍过的arange函数创建一个矩阵
这里用arange中的reshape函数创建了一个6*4的矩阵,如果不指定,默认就是一行的矩阵
A = np.arange(24).reshape(6,4)
结果为:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])
创建好矩阵之后来一写进阶的计算:
1)sum函数
axis就是确定沿矩阵的行或者列进行加和
axis=0:沿着每一列进行操作(所以返回4个值)
axis=1:沿着每一行进行操作(6个行返回六个值)
A.sum(axis=0)
A.sum(axis=1)
axis=0的结果:
array([60, 66, 72, 78])
axis=1的结果:
array([ 6, 22, 38, 54, 70, 86])
2)cumsum函数
axis就是确定沿矩阵的行或者列进行加和
axis=0:沿着每一列对这个位置及之前位置的元素累加
axis=1:沿着每一行对这个位置及之前位置的元素累加
A.cumsum(axis=1)
A.cumsum(axis=0)
axis=1的结果:
array([[ 0, 1, 3, 6],
[ 4, 9, 15, 22],
[ 8, 17, 27, 38],
[12, 25, 39, 54],
[16, 33, 51, 70],
[20, 41, 63, 86]], dtype=int32)
axis=0的结果:
array([[ 0, 1, 2, 3],
[ 4, 6, 8, 10],
[12, 15, 18, 21],
[24, 28, 32, 36],
[40, 45, 50, 55],
[60, 66, 72, 78]], dtype=int32)
3.min函数
axis就是确定沿矩阵的行或者列取最小值
axis=0:沿着每一列取最小值
axis=1:沿着每一行取最大值
A.min(axis=0)
A.min(axis=1)
axis=0的结果:
array([0, 1, 2, 3])
axis=1的结果:
array([ 0, 4, 8, 12, 16, 20])
像这样的函数还有很多,不再一一介绍,不过都是按照axis=1按列操作,axis=0按行操作的规律进行的。
矩阵元素的选取:
a = np.arange(10)**2
array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81], dtype=int32)
选取某个位置的元素:
a[5]
25
从结果是25可以看出,下标是从0开始计数。
选取某几个元素:
从结果可以看出,选取的元素是从第一个参数开始,第二个参数为止且不包含第二个参数位置的元素。
a[1:3]
array([1, 4], dtype=int32)
下面介绍一个大家在复制矩阵时有可能遇到的坑~
a_slice = a[0:5]
array([100, 100, 100, 9, 16], dtype=int32)
这里选取了0-4位置的元素变成一个新的array,下面对此array进行操作:
可以看到该操作,也同样对a产生了影响,因为,当选取部分np array的时候,我们创建了一个view,也就是说,我们没有copy之前的值,而是直接改了原来的array。
a_slice[0]=222
a_slice
array([222, 100, 100, 9, 16], dtype=int32)
a
array([222, 100, 100, 9, 16, 25, 36, 49, 64, 81], dtype=int32)
那么,如果我们不想改变之前的array怎么办呢?
这时,就用到了copy函数,是指将数据copy到新的array中并不对原array产生影响。
a_slice_2 = a[0:5].copy()
a_slice_2[1]=222
array([222, 222, 100, 9, 16], dtype=int32)
下面总结一下用方程建矩阵,及多维矩阵的选取和切片:
def f(x,y):
return 4 * x +y
b = np.fromfunction(f,(3,2),dtype=int)
b
这里我们就自定义了一个函数f,下面用fromfunction方法创建一个三行两列的数组
结果为:
array([[0, 1],
[4, 5],
[8, 9]])
array的选取:
[:]:仅针对行的操作
[:,]:对行和列的选取
#全选
b[:]
array([[0, 1],
[4, 5],
[8, 9]])
#从某行开始选到某行结束
b[:1]
array([[0, 1]])
#选取所有行和第一列
b[:,1]
array([1, 5, 9])
#选取行
b[1]
array([4, 5])
#选取某个位置的元素
b[1,0]
4
这里再说一些shape函数的用法,之前博文中也有提到:
这里0指的是该矩阵有几行,1代表这个矩阵有几列
b.shape[0]
3
b.shape[1]
2
矩阵的转至,先举一个一般的矩阵的转至,以上面的b矩阵为例:
b.T
array([[0, 4, 8],
[1, 5, 9]])
那么对于堆矩阵,如何转至呢?
首先创建一个堆:
c=np.array([[[1,2,3,0],[3,4,5,2]]])
c.shape
这是一个一堆两行四列的矩阵
array([[[1, 2, 3, 0],
[3, 4, 5, 2]]])
(1, 2, 4)
直接使用T转至函数:
c.T
结果为:
array([[[1],
[3]],
[[2],
[4]],
[[3],
[5]],
[[0],
[2]]])
看下转至后的类型:可以看到是原来的每列变成堆,所以变成4堆,整体变为4堆两行一列
c.T.shape
(4, 2, 1)
这时候就有一个进阶函数,可以指定转变的方式
c.transpose(0,2,1)
三个参数的意思是,第一个维度不变,后面两个维度交换位置,那形状就变成了一堆四行两列
结果为:
array([[[1, 3],
[2, 4],
[3, 5],
[0, 2]]])
求逆矩阵
a1 = np.mat([[3,4],[2,16]])
np.linalg.inv(np.dot(a1.T,a1))
结果为:
matrix([[ 0.17 , -0.0275 ],
[-0.0275 , 0.008125]])
比较两个矩阵是否相同:
a = np.array([[1.,2.],[3.,4.]])
ainv = np.linalg.inv(a)
np.allclose(np.dot(a,ainv),np.eye(2))
结果为:
True
以上就是一些介绍啦~