NumPy数组&矩阵运算

NumPy数组&矩阵运算

只列举了一些常用的,NumPy提供了巨多数学函数,堪称Python版MatLib,有兴趣可以查询NumPy的中文文档https://www.numpy.org.cn/

目录

  • NumPy数组&矩阵运算
    • 基本运算
      • 数组与数值的算术运算:加减乘除,幂余补等等
      • 数组与数组的算术运算
      • 向量点积
      • 三角函数运算
      • 四舍五入
      • 对矩阵不同维度上的元素进行求和
      • 计算数据的标准差和方差
      • 对矩阵不同维度上的元素求最大值
      • 对矩阵不同维度上的元素进行排序
      • 生成特殊数组
      • 布尔运算
      • 取整运算
      • 分段函数
      • 计算唯一值以及出现次数
      • 计算加权平均值
    • 线性代数运算

基本运算

数组与数值的算术运算:加减乘除,幂余补等等

a = np.array((1,2,3,4,5))
print(a*2)
[ 2  4  6  8 10]
a = np.array((2,4,6,8,10))
print(a/2)
[1. 2. 3. 4. 5.]
a = np.array((1,2,3,4,5))
print(a**2)
[ 1  4  9 16 25]

数组与数组的算术运算

a = np.array([1,2,3])
b = np.array([[1,2,3],[4,5,6],[7,8,9]])
c = a*b # 自动调用广播机制,将扩展为3x3,然后再进行运算 
print(c)
[[ 1  4  9]
 [ 4 10 18]
 [ 7 16 27]]
print(c/b)
[[1. 2. 3.]
 [1. 2. 3.]
 [1. 2. 3.]]

向量点积

a = np.array([5,6,7])
b = np.array([6,6,6])
print(np.dot(a,b))
108

三角函数运算

b = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(np.sin(b))
[[ 0.84147098  0.90929743  0.14112001]
 [-0.7568025  -0.95892427 -0.2794155 ]
 [ 0.6569866   0.98935825  0.41211849]]
print(np.cos(b))
[[ 0.54030231 -0.41614684 -0.9899925 ]
 [-0.65364362  0.28366219  0.96017029]
 [ 0.75390225 -0.14550003 -0.91113026]]

四舍五入

print(np.sin(b))
print(np.round(np.sin(b)))
[[ 0.84147098  0.90929743  0.14112001]
 [-0.7568025  -0.95892427 -0.2794155 ]
 [ 0.6569866   0.98935825  0.41211849]]
[[ 1.  1.  0.]
 [-1. -1. -0.]
 [ 1.  1.  0.]]

对矩阵不同维度上的元素进行求和

x = np.arange(0,10).reshape(2,5)
print(x)
np.sum(x) # 所有矩阵元素之和
[[0 1 2 3 4]
 [5 6 7 8 9]]

45
np.sum(x,axis=0) # 按行求和(行与行相加)
array([ 5,  7,  9, 11, 13])
np.sum(x,axis=1) # 按列求和
array([10, 35])

计算数据的标准差和方差

x =np.random.randint(0,12,size=(3,4))
print(x)
[[10  0  0  5]
 [ 8  2  7  3]
 [11  4  8  3]]
# 求标准差
print(np.std(x))
print(np.std(x,axis=1)) # 计算每一行的标准差
3.5463204718255357
[4.14578099 2.54950976 3.20156212]
# 方差
print(np.var(x))
print(np.var(x,axis=0)) # 计算每一列的方差
12.576388888888891
[ 1.55555556  2.66666667 12.66666667  0.88888889]

对矩阵不同维度上的元素求最大值

print(x)
print(np.max(x)) # 该矩阵中所有元素中的最大值
print(np.max(x,axis=1)) # 分行求最大值
[[10  0  0  5]
 [ 8  2  7  3]
 [11  4  8  3]]
11
[10  8 11]

对矩阵不同维度上的元素进行排序

print(x)
print(np.sort(x)) # 默认是分行排序
print(np.sort(x,axis=0)) # 按列排序
[[10  0  0  5]
 [ 8  2  7  3]
 [11  4  8  3]]
[[ 0  0  5 10]
 [ 2  3  7  8]
 [ 3  4  8 11]]
[[ 8  0  0  3]
 [10  2  7  3]
 [11  4  8  5]]

生成特殊数组

print(np.zeros((3,3)))
[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]
print(np.ones((3,3)))
[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]
print(np.identity(3)) # 单位矩阵,只需要指定维度即可
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
print(np.empty((4,4))) # 只申请空间,不初始化,速度很快
[[6.23042070e-307 4.67296746e-307 1.69121096e-306 4.67293691e-307]
 [1.33508845e-306 1.33511969e-306 6.23037996e-307 1.69121639e-306]
 [1.00136982e-307 3.11523242e-307 2.22523004e-306 1.78021527e-306]
 [6.23059726e-307 1.33511562e-306 6.89805151e-307 1.11261909e-306]]

布尔运算

x = np.random.rand(10)
print(x)
[0.07449286 0.37570348 0.91359089 0.99129463 0.35884467 0.53426686
 0.50733014 0.17927154 0.34265881 0.49000799]
x1 = x>0.5  # 这样得到的是bool数组
print(x1)
[False False  True  True False  True  True False False False]
x2 = x[x>0.5] # 这样得到的是满足条件的数值数组
print(x2)
[0.91359089 0.99129463 0.53426686 0.50733014]

取整运算

import numpy as np
x= np.random.rand(10)*50
print(x)
print(np.ceil(x)) # 向上取整
print(np.floor(x)) #向下取整
[ 4.68343336  9.49065354 36.32606569 27.91724177 20.52149291  8.42613216
 49.03588452 28.24044111 15.59059753 24.93902631]
[ 5. 10. 37. 28. 21.  9. 50. 29. 16. 25.]
[ 4.  9. 36. 27. 20.  8. 49. 28. 15. 24.]

分段函数

x =np.random.randint(0,10,size=(1,10))
print(x)
[[3 5 8 0 5 2 7 6 2 2]]
""" 
where(x<5,0,1) 
相当于 if x<5:
            x=0 
        else:
            x=1
"""
np.where(x<5,0,1) 
array([[0, 1, 1, 0, 1, 0, 1, 1, 0, 0]])
x = np.random.randint(0,10,size=(1,10))
print(x)
[[4 5 1 2 6 9 9 0 4 2]]
"""
piecewise(x,[x>7,x<4],[lambda x:x+2,lambda x:x*3,0])
等价代码:
if x >7:
    x = x+2
elif x<4:
    x=x*3
else:
    x=0
"""
np.piecewise(x,[x>7,x<4],[lambda x:x+2,lambda x:x*3,0])
array([[ 0,  0,  3,  6,  0, 11, 11,  0,  0,  6]])

计算唯一值以及出现次数

x = np.random.randint(0,10,10)
print(x)
[1 1 4 9 1 2 0 9 8 6]
#我们可以看到x中最大的数为9,因此bin的数量为10,那么它的索引值为0->9
#索引0出现了1次,索引1出现了3次,索引2出现了1次,索引3出现了0次,索引4出现了1次....索引8出现了1次,索引9出现了2次
# 所以结果如下
np.bincount(x)
array([1, 3, 1, 0, 1, 0, 1, 0, 1, 2], dtype=int64)
np.unique(x) # 去重
array([0, 1, 2, 4, 6, 8, 9])

计算加权平均值

x =np.random.randint(0,10,10)
print(x)
[4 2 8 1 4 9 8 4 1 9]
# 设置加权矩阵,在机器学习中,这个矩阵通常是w(weight)矩阵
y=np.array([round(i,1) for i in list(np.random.random(10))]) # round(i,n) 将i四舍五入到小数点后n位
print(y)
[0.4 0.4 0.8 0.9 0.5 0.4 0.2 0.2 0.6 0.2]
np.sum(x*y)/np.sum(np.bincount(x))
2.71

线性代数运算

先明确两个概念:

1、矩阵内积 matmul()函数

假如有矩阵A和矩阵B他们都是两行两列,则内积计算结果也为两行两列的一个矩阵,假设C为内积矩阵,计算公式如下。

C[0,0]=A[0,0] *B[0,0] + A[0,1] *B[1,0]:A的第一行与B的第一列,对应元素的乘积之和;

C[0,1]=A[0,0] *B[0,1] + A[0,1] *B[1,1]:A的第一行与B的第二列,对应元素的乘积之和;

C[1,0]=A[1,0] *B[0,0] + A[1,1] *B[1,0]:A的第二行与B的第一列,对应元素的乘积之和;

C[1,1]=A[1,1] *B[0,1] + A[1,1] *B[1,1]:A的第二行与B的第二列,对应元素的乘积之和;

2、数组内积 inner()函数

数组的内积是两个数组的行与行乘积和运算,同上有数组A和B,则计算公式如下

C[0,0]=A[0,0] *B[0,0] + A[0,1] *B[0,1];

C[0,1]=A[0,0] *B[1,0] + A[0,1] *B[1,1];

C[1,0]=A[1,0] *B[0,0] + A[1,1] *B[0,1];

C[1,1]=A[1,0] *B[1,0] + A[1,1] *B[1,1];
函数 描述
dot 如果处理的是一维数组,则得到的是两数组的內积 如果是二维数组(矩阵)之间的运算,则得到的是矩阵积(mastrix product)
vdot 两个向量的点积,即每个元素与其对应的另一个矩阵的元素相乘并求和
inner 一维数组点积,高维数组内积
matmul 两个数组的矩阵积
determinant 数组的行列式
solve 求解线性矩阵方程
inv 计算矩阵的乘法逆矩阵
# 求矩阵a,b的内积
import numpy.matlib
import numpy as np
 
a = np.array([[1,2],[3,4]])
print(a)
b = np.array([[11,12],[13,14]])
print(b)
# [[1*11+2*13, 1*12+2*14],[3*11+4*13, 3*12+4*14]]
print(np.dot(a,b))
[[1 2]
 [3 4]]
[[11 12]
 [13 14]]
[[37 40]
 [85 92]]
# 求两个向量的点积
import numpy as np 
 
a = np.array([[1,2],[3,4]]) 
print(a)
b = np.array([[11,12],[13,14]]) 
print(b) 
    
# vdot 将数组展开计算内积:1*11 + 2*12 + 3*13 + 4*14 = 130
print (np.vdot(a,b))
[[1 2]
 [3 4]]
[[11 12]
 [13 14]]
130
import numpy as np 
 
print (np.inner(np.array([1,2,3]),np.array([0,1,0])))
# 等价于 1*0+2*1+3*0
2
#多维数组之间使用inner, 。
a = np.array([[1,2], [3,4]]) 
 
print ('数组 a:')
print (a)
b = np.array([[11, 12], [13, 14]]) 
 
print ('数组 b:')
print (b)
 
print ('内积:')
"""
1*11+2*12, 1*13+2*14 
3*11+4*12, 3*13+4*14
"""
print (np.inner(a,b))
数组 a:
[[1 2]
 [3 4]]
数组 b:
[[11 12]
 [13 14]]
内积:
[[35 41]
 [81 95]]
import numpy.matlib 
import numpy as np 
 
a = [[1,0],[0,1]] 
print(a)
b = [[4,1],[2,2]] 
print(b)
print("矩阵内积:")
print (np.matmul(a,b))
[[1, 0], [0, 1]]
[[4, 1], [2, 2]]
矩阵内积:
[[4 1]
 [2 2]]
# 二维矩阵内积一维矩阵
import numpy.matlib 
import numpy as np 
 
a = [[1,2],[0,1]] 
b = [1,2]  
print("axb")
print (np.matmul(a,b))
print("bxa") # 本来是无法进行相乘的,但是numpy会自动将b矩阵转置再与a矩阵相乘
print (np.matmul(b,a))
axb
[5 2]
bxa
[1 4]
# 维度大于2的数组之间求矩阵内积
import numpy.matlib 
import numpy as np 
 
a = np.arange(8).reshape(2,2,2) 
print("a矩阵")
print(a)
b = np.arange(4).reshape(2,2) 
print("b矩阵")
print(b)
print("axb=[a[0]xb,a[1]xb]:")
print (np.matmul(a,b))
a矩阵
[[[0 1]
  [2 3]]

 [[4 5]
  [6 7]]]
b矩阵
[[0 1]
 [2 3]]
axb=[a[0]xb,a[1]xb]:
[[[ 2  3]
  [ 6 11]]

 [[10 19]
  [14 27]]]
# 求行列式
import numpy as np
a = np.array([[1,2], [3,4]]) 
print(a)
print("1x4-2x3...")
print (np.linalg.det(a))
[[1 2]
 [3 4]]
1x4-2x3...
-2.0000000000000004
import numpy as np
 
b = np.array([[6,1,1], [4, -2, 5], [2,8,7]]) 
print (b)
print("计算过程..")
print ("6*(-2*7 - 5*8) - 1*(4*7 - 5*2) + 1*(4*8 - -2*2)")
print("result:")
print (np.linalg.det(b))

[[ 6  1  1]
 [ 4 -2  5]
 [ 2  8  7]]
计算过程..
6*(-2*7 - 5*8) - 1*(4*7 - 5*2) + 1*(4*8 - -2*2)
result:
-306.0
# 矩阵求逆
import numpy as np 
 
x = np.array([[1,2],[3,4]]) 
y = np.linalg.inv(x) 
print (x)
print (y)
print (np.dot(x,y))
[[1 2]
 [3 4]]
[[-2.   1. ]
 [ 1.5 -0.5]]
[[1.00000000e+00 1.11022302e-16]
 [0.00000000e+00 1.00000000e+00]]

numpy.linalg.solve() 函数给出了矩阵形式的线性方程的解。

考虑以下线性方程:
x + y + z = 6 x+y+z=6 x+y+z=6
2 y + 5 z = − 4 2y+5z=-4 2y+5z=4
2 x + 5 y − z = 27 2x+5y-z=27 2x+5yz=27
可以得到矩阵形式的方程:
A X = Y AX = Y AX=Y
X = A − 1 Y X=A^{-1}Y X=A1Y

import numpy as np 
 
a = np.array([[1,1,1],[0,2,5],[2,5,-1]]) 
 
print ('数组 A:')
print (a)
ainv = np.linalg.inv(a) 
 
print ('A 的逆:')
print (ainv)
 
print ('矩阵 Y:')
y = np.array([[6],[-4],[27]]) 
print (y)
 
print ('计算:A^(-1)Y:')
x = np.linalg.solve(a,y) 
print("通过np.linalg.solve(a,y)计算得:")
print (x)
# 这就是线性方向 x = 5, y = 3, z = -2 的解
# 结果也可以使用以下函数获取
print("通过np.dot(ainv,y)计算得:")
x2 = np.dot(ainv,y)
print(x2)

数组 A:
[[ 1  1  1]
 [ 0  2  5]
 [ 2  5 -1]]
A 的逆:
[[ 1.28571429 -0.28571429 -0.14285714]
 [-0.47619048  0.14285714  0.23809524]
 [ 0.19047619  0.14285714 -0.0952381 ]]
矩阵 Y:
[[ 6]
 [-4]
 [27]]
计算:A^(-1)Y:
通过np.linalg.solve(a,y)计算得:
[[ 5.]
 [ 3.]
 [-2.]]
通过np.dot(ainv,y)计算得:
[[ 5.]
 [ 3.]
 [-2.]]

你可能感兴趣的:(NumPy数组&矩阵运算)