Python——第6章 Numpy库的使用

Numpy 是 Python 专门处理高维数组 (high dimensional array) 的计算的包。

官网 (www.numpy.org).

列表和数组区别

列表:数据类型可以不同——3.1413, 'pi', 3.1404, [3.1401, 3.1349], '3.1376'

数组:数据类型相同——3.1413, 3.1398, 3.1404, 3.1401, 3.1349, 3.1376

1numpy数组及其运算

1.1创建数组

import numpy as np
np.array([1,2,3,4,5])#把列表转为数组
array([1, 2, 3, 4, 5])
np.array((1,2,3,4,5))#把元组转换为数组
array([1, 2, 3, 4, 5])
np.array(range(5))#把range对象转换成数组
array([0, 1, 2, 3, 4])
np.array([[1,2,3],[4,5,6]])#二维数组
array([[1, 2, 3],
       [4, 5, 6]])

数组的创建—定隔定点的 np.arange() 和 np.linspace()

更常见的两种创建 numpy 数组方法:

(1)定隔的 arange:固定元素大小间隔:arange(start , stop , step)

说明:其中 stop 必须要有,start 和 step 没有的话默认为 1。

np.arange(8)
array([0, 1, 2, 3, 4, 5, 6, 7])
np.arange(1,10,2)
array([1, 3, 5, 7, 9])

(2)定点的 linspace:固定元素个数: linspace (start , stop , num)

说明:其中 start 和 stop 必须要有,num 没有的话默认为 50。

np.linspace(0,10,11)#等差数组,包含11个数
array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])
np.linspace(0,10,11,endpoint=False)#不包含终点
array([0.        , 0.90909091, 1.81818182, 2.72727273, 3.63636364,
       4.54545455, 5.45454545, 6.36363636, 7.27272727, 8.18181818,
       9.09090909])
np.logspace(0,100,10)#相当于10**np.linspace(0,100,10)
array([1.00000000e+000, 1.29154967e+011, 1.66810054e+022, 2.15443469e+033,
       2.78255940e+044, 3.59381366e+055, 4.64158883e+066, 5.99484250e+077,
       7.74263683e+088, 1.00000000e+100])
np.logspace(1,6,5,base=2)#相当于2*np.linspace(1,6,5)
array([ 2.        ,  4.75682846, 11.3137085 , 26.90868529, 64.        ])

数组的创建—使用NumPy中函数创建ndarray数组

np.zeros(3)#全0一维数组
array([0., 0., 0.])
np.ones(3)
array([1., 1., 1.])
np.zeros((3,3))#全0二维数组,3行3列
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])
np.zeros((1,3))#全0二维数组,1行3列
array([[0., 0., 0.]])
np.zeros((3,1))
array([[0.],
       [0.],
       [0.]])
np.ones((3,3))
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
np.ones((1,3))
array([[1., 1., 1.]])
np.identity(3)#单位矩阵
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
np.identity(2)
array([[1., 0.],
       [0., 1.]])
np.empty((3,3))#空数组,只申请空间,不初始化
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
np.eye(3) # 单位矩阵,3行3列
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
np.hamming(20)#Hamming窗口
array([0.08      , 0.10492407, 0.17699537, 0.28840385, 0.42707668,
       0.5779865 , 0.7247799 , 0.85154952, 0.94455793, 0.9937262 ,
       0.9937262 , 0.94455793, 0.85154952, 0.7247799 , 0.5779865 ,
       0.42707668, 0.28840385, 0.17699537, 0.10492407, 0.08      ])
np.blackman(10)#Blackman窗口
array([-1.38777878e-17,  5.08696327e-02,  2.58000502e-01,  6.30000000e-01,
        9.51129866e-01,  9.51129866e-01,  6.30000000e-01,  2.58000502e-01,
        5.08696327e-02, -1.38777878e-17])
np.kaiser(12,5)#Kaiser窗口
array([0.03671089, 0.16199525, 0.36683806, 0.61609304, 0.84458838,
       0.98167828, 0.98167828, 0.84458838, 0.61609304, 0.36683806,
       0.16199525, 0.03671089])

使用random() 创建随机 n 维数组

np.random.randint(0,50,5)
array([28,  2, 43, 17, 22])
np.random.randint(0,50,(3,5))
array([[12, 47, 33, 10,  2],
       [23,  6, 17,  7, 24],
       [11, 39, 24, 26, 30]])
np.random.rand(10)
array([0.09670211, 0.99259248, 0.5341233 , 0.71901056, 0.90347888,
       0.91331606, 0.08372737, 0.79742945, 0.31878994, 0.55094098])
np.random.standard_normal(5)#从标准正态分布中随机采样5个数字
array([-0.14415678,  1.08512822,  0.99102915, -0.49645761, -1.51070848])
x=np.random.standard_normal(size=(3,4,2))#3页4行2列
x
array([[[ 0.85754025, -0.28172407],
        [ 0.23733268,  0.87116374],
        [-0.62887857, -1.36845296],
        [-0.53553569,  1.01818603]],

       [[-0.48036281,  0.30293107],
        [-0.41027798,  0.87720648],
        [-0.74450358, -0.60304887],
        [-0.48493204, -1.9946126 ]],

       [[ 0.19694871,  0.53144363],
        [ 0.032769  , -1.362219  ],
        [-0.03665392,  1.49506453],
        [ 1.55785374, -0.96754543]]])
np.diag([1,2,3,4])                 # 对角矩阵
array([[1, 0, 0, 0],
       [0, 2, 0, 0],
       [0, 0, 3, 0],
       [0, 0, 0, 4]])

1.2测试两个数组的对应元素是否足够接近

import numpy as np
x=np.array([1,2,3,4.001,5])
y=np.array([1,1.999,3,4.01,5.1])
print(np.allclose(x,y))
print(np.allclose(x,y,rtol=0.2))#设置相对误差
print(np.allclose(x,y,atol=0.2))#设置绝对参数
print(np.isclose(x,y))
print(np.isclose(x,y,atol=0.2))
False
True
True
[ True False  True False False]
[ True  True  True  True  True]

1.3修改数组中的元素值

import numpy as np
x=np.arange(8)
x
array([0, 1, 2, 3, 4, 5, 6, 7])
np.append(x,8) # 返回新数组,在尾部追加一个元素
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
np.append(x,[9,10]) # 返回新数组,在尾部追加多个元素
array([ 0,  1,  2,  3,  4,  5,  6,  7,  9, 10])
x              # 不影响原来的数组
array([0, 1, 2, 3, 4, 5, 6, 7])
x[3]=8   # 使用下标的形式原地修改元素值
x        # 原来的数组被修改了
array([0, 1, 2, 8, 4, 5, 6, 7])
np.insert(x,1,8)   # 返回新数组,插入元素
array([0, 8, 1, 2, 8, 4, 5, 6, 7])
x=np.array([[1,2,3],[4,5,6],[7,8,9]])
x[0,2]=4          # 修改第0行第2列的元素值
x[1:,1:]=1       # 切片,把行下标大于等于1
x
array([[1, 2, 4],
       [4, 1, 1],
       [7, 1, 1]])
x[1:,1:]=[1,2]    # 同时修改多个元素值
x
array([[1, 2, 4],
       [4, 1, 2],
       [7, 1, 2]])
x[1:,1:]=[[1,2],[3,4]] # 同时修改多个元素值
x
array([[1, 2, 4],
       [4, 1, 2],
       [7, 3, 4]])

1.4数组与标量的运算

import numpy as np
x=np.array((1,2,3,4,5)) # 创建数组对象
x
array([1, 2, 3, 4, 5])
x*2       # 数组与数值相乘,返回新数组
array([ 2,  4,  6,  8, 10])
x/2        # 数组与数值相除
array([0.5, 1. , 1.5, 2. , 2.5])
x//2        # 数组与数值相除
array([0, 1, 1, 2, 2], dtype=int32)
x**3        # 幂运算
array([  1,   8,  27,  64, 125], dtype=int32)
x+2         # 数组与数值相加
array([3, 4, 5, 6, 7])
x%3         # 余数
array([1, 2, 0, 1, 2], dtype=int32)
2**x           # 分别计算2**1、2**2、2**3、2**4、2**5
array([ 2,  4,  8, 16, 32], dtype=int32)
2/x
array([2.        , 1.        , 0.66666667, 0.5       , 0.4       ])
63//x
array([63, 31, 21, 15, 12], dtype=int32)

1.5数组与数组的运算

np.array([1,2,3,4])+np.array([4,3,2,1])      # 等长数组相加,对应元素相加,返回信数组
array([5, 5, 5, 5])
np.array([1,2,3,4])+np.array([4])      # 数组中每个元素加4,数组不等长
array([5, 6, 7, 8])
a=np.array((1,2,3))                    
a + a              # 等长数组之间的加法运算,对应元素相加
array([2, 4, 6])
a * a              # 等长数组之间的乘法运算,对应元素相乘
array([1, 4, 9])
a - a           # 等长数组之间的减法运算,对应元素相减
array([0, 0, 0])
a / a           # 等长数组之间的除法运算,对应元素相除
array([1., 1., 1.])
a**a            # 等长数组之间的幂运算,对应元素乘方
array([ 1,  4, 27], dtype=int32)
b=np.array(([1,2,3],[4,5,6],[7,8,9]))
c=a*b         # 不同维度的数组与数组相乘
c            # a中的每个元素乘以b中对应列的元素
             # a中下标0的元素乘以b中列下标0的元素
             # a中下标1的元素乘以b中列下标1的元素
             # a中下标2的元素乘以b中列下标2的元素
array([[ 1,  4,  9],
       [ 4, 10, 18],
       [ 7, 16, 27]])
a+b       # a中每个元素加b中的对应列元素
array([[ 2,  4,  6],
       [ 5,  7,  9],
       [ 8, 10, 12]])

1.6数组排序

import numpy as np
x=np.array([3,1,2])
np.argsort(x)         # 返回升序排序后元素的原下标
                      # 原数组中下标1的元素最小
                      # 下标2的元素次之
                      # 下标0的元素最大
array([1, 2, 0], dtype=int64)
x[_]                # 使用数组做下标,获取对应位置的元素
array([1, 2, 3])
x=np.array([3,1,2,4])
x.argmax(),x.argmin() # 最大值和最小值的下标
(3, 1)
np.argsort(x)
array([1, 2, 0, 3], dtype=int64)
x[_]
array([1, 2, 3, 4])
x.sort()         # 原地排序
x
array([1, 2, 3, 4])
x=np.random.randint(1,10,(2,5))
x
array([[3, 2, 6, 9, 9],
       [8, 5, 5, 1, 1]])
x.sort(axis=1)#横向排序
x
array([[2, 3, 6, 9, 9],
       [1, 1, 5, 5, 8]])

1.7数组的内积运算

\[x·y=\sum^n _{i=1}{x_iy_i} \]

x=np.array((1,2,3))
y=np.array((4,5,6))
print(np.dot(x,y))#内积
print(x.dot(y))
print(sum(x*y))
32
32
32

1.8访问数组中的元素

b=np.array(([1,2,3],[4,5,6],[7,8,9]))
b
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
b[0]      # 第0行所有元素     
array([1, 2, 3])
b[0][0]    # 第0行第0列的元素
1
b[0,2]     # 第0行第2列的元素,等价于b[0][2]的形式
3
b[[0,1]]   # 第0行和第1行的所有元素,只指定行下标,不指定列下标,表示所有列
array([[1, 2, 3],
       [4, 5, 6]])
b[[0,2,1],[2,1,0]]  # 第0行第2列、第2行第1列、第1行第0列的元素
                    # 第一个列表表示行下标,第二个列表表示列下标
array([3, 8, 4])
a=np.arange(10)
a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
a[::-1] # 反向切片
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
a[::2] # 隔一个取一个元素
array([0, 2, 4, 6, 8])
a[:5]  # 前5个元素
array([0, 1, 2, 3, 4])
c=np.arange(25)
c
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, 24])
c.shape=5,5   # 修改数组形状
c
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, 24]])
c[0,2:5]    # 第0行中下标[2,5)之间的元素值
array([2, 3, 4])
c[1]       # 第0行中下标[2,5)之间的元素值
array([5, 6, 7, 8, 9])
c[2:5,2:5]  # 行下标和列下标都介于[2,5)之间的元素值
array([[12, 13, 14],
       [17, 18, 19],
       [22, 23, 24]])
c[[1,3],[2,4]]  # 第1行第2列的元素和第3行第4列的元素
array([ 7, 19])
c[[1,3],2:4]     # 第1行和第3行的第2、3列
array([[ 7,  8],
       [17, 18]])
c[:,3]        # 第3列所有元素
array([ 3,  8, 13, 18, 23])
c[:, [2,4]]          # 第2列和第4列所有元素,对行下标进行切片,冒号表示所有行
array([[ 2,  4],
       [ 7,  9],
       [12, 14],
       [17, 19],
       [22, 24]])
c[[1,3]]     # 第1行和第3行所有元素
array([[ 5,  6,  7,  8,  9],
       [15, 16, 17, 18, 19]])
c[[1,3]][:,[2,4]]   # 第1、3行的2、4列元素
array([[ 7,  9],
       [17, 19]])

1.9数组对函数运算的支持

x=np.arange(0,100,10,dtype=np.floating)
print(x)
print(np.sin(x))   # 一维数组中所有元素求正弦值
[ 0. 10. 20. 30. 40. 50. 60. 70. 80. 90.]
[ 0.         -0.54402111  0.91294525 -0.98803162  0.74511316 -0.26237485
 -0.30481062  0.77389068 -0.99388865  0.89399666]


C:\Users\soul学长\AppData\Local\Temp/ipykernel_6100/3916564714.py:1: DeprecationWarning: Converting `np.inexact` or `np.floating` to a dtype is deprecated. The current result is `float64` which is not strictly correct.
  x=np.arange(0,100,10,dtype=np.floating)
x=np.array(([1,2,3],[4,5,6],[7,8,9]))
print(x)       
[[1 2 3]
 [4 5 6]
 [7 8 9]]
print(np.cos(x)) # 二维数组中所有元素求余弦值
[[ 0.54030231 -0.41614684 -0.9899925 ]
 [-0.65364362  0.28366219  0.96017029]
 [ 0.75390225 -0.14550003 -0.91113026]]
print(np.round(np.cos(x)))  # 四舍五入
[[ 1. -0. -1.]
 [-1.  0.  1.]
 [ 1. -0. -1.]]
print(np.ceil(x/2))   #向上取整
[[1. 1. 2.]
 [2. 3. 3.]
 [4. 4. 5.]]

1.10改变数组形状

x=np.arange(1,11,1)
x
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
x.shape  # 查看数组的形状
(10,)
x.size   # 数组中元素的数量
10
x.shape=2,5   # 改为2行5列
x
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
x.shape
(2, 5)
x.shape=5,-1     # -1表示自动计算
x
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10]])
x=x.reshape(2,5)   # reshape()方法返回新数组
x
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
x=np.array(range(5))
x.reshape((1,10))   # reshape()不能修改数组元素个数,出错
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_6100/1914000034.py in <module>
----> 1 x.reshape((1,10))   # reshape()不能修改数组元素个数,出错


ValueError: cannot reshape array of size 5 into shape (1,10)
x.resize((1,10))   # reshape()不能修改数组元素个数,出错
x
array([[0, 1, 2, 3, 4, 0, 0, 0, 0, 0]])
np.resize(x,(1,3))  # 使用numpy的resize()返回新数组
array([[0, 1, 2]])
x         # 不对原数组进行任何修改
array([[0, 1, 2, 3, 4, 0, 0, 0, 0, 0]])

1.11数组布尔运算

x=np.random.rand(10)      # 包含10个随机数的数组
x
array([0.23494488, 0.62911978, 0.08695988, 0.49816789, 0.78656564,
       0.41347271, 0.09284217, 0.50007711, 0.37424032, 0.38977916])
x>0.5         # 比较数组中每个元素值是否大于0.5
array([False,  True, False, False,  True, False, False,  True, False,
       False])
x[x>0.5]      # 获取数组中大于0.5的元素
array([0.62911978, 0.78656564, 0.50007711])
x<0.5         # 获取数组中大于0.5的元素
array([ True, False,  True,  True, False,  True,  True, False,  True,
        True])
sum((x>0.4)&(x<0.6))     # 值大于0.4且小于0.6的元素数量,True表示1,False表示0
3
np.all(x<1)        # 测试是否全部元素都小于1
True
np.any(x>0.8)     # 是否存在大于0.8的元素
False
a=np.array([1,2,3])
b=np.array([3,2,1])
a>b                # 两个数组中对应位置上的元素比较
array([False, False,  True])
a[a>b]               # 数组a中大于b数组对应位置上元素的值
array([3])
a==b
array([False,  True, False])
a[a==b]
array([2])
x=np.arange(1,10)
x
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
x[(x%2==0)&(x>5)]         # 大于5的偶数,两个数组进行布尔与运算
array([6, 8])
x[(x%2==0)&(x>5)]        # 大于5的元素或者偶数元素,布尔或运算
array([6, 8])

1.12分段函数

x=np.random.randint(0,10,size=(1,10))
x
array([[7, 5, 6, 0, 8, 6, 3, 7, 6, 2]])
np.where(x<5,0,1)#小于5的元素值对应0,其他对应1
array([[1, 1, 1, 0, 1, 1, 0, 1, 1, 0]])
x.resize((2,5))
x
array([[7, 5, 6, 0, 8],
       [6, 3, 7, 6, 2]])
# 小于4的元素乘以2,大于7的元素乘以3,其他元素变为0
np.piecewise(x,[x<3,x>7],[lambda x:x*2,lambda x:x*3]) 
array([[ 0,  0,  0,  0, 24],
       [ 0,  0,  0,  0,  4]])
# 小于3的元素变为-1,大于3小于5的元素变为1,大于7的元素乘以4
# 条件没有覆盖到的其他元素变为0
np.piecewise(x,[x<3,(3<x)&(x<5),x>7],[-1,1,lambda x:x*4])
array([[ 0,  0,  0, -1, 32],
       [ 0,  0,  0,  0, -1]])

1.13数组堆叠与合并

arr1=np.array([1,2,3])
arr2=np.array([4,5,6])
np.hstack((arr1,arr2))#水平堆叠
array([1, 2, 3, 4, 5, 6])
np.vstack((arr1,arr2))#垂直堆叠
array([[1, 2, 3],
       [4, 5, 6]])
arr3=np.array([[1],[2],[3]])
arr4=np.array([[4],[5],[6]])
arr3
array([[1],
       [2],
       [3]])
arr4
array([[4],
       [5],
       [6]])
np.hstack((arr3,arr4))
array([[1, 4],
       [2, 5],
       [3, 6]])
np.vstack((arr3,arr4))
array([[1],
       [2],
       [3],
       [4],
       [5],
       [6]])
np.concatenate((arr1,arr2))
array([1, 2, 3, 4, 5, 6])
np.concatenate((arr3,arr4))
array([[1],
       [2],
       [3],
       [4],
       [5],
       [6]])
np.concatenate((arr3,arr4),axis=1)
array([[1, 4],
       [2, 5],
       [3, 6]])

2矩阵生成与常用操作

2.1矩阵生成

x=np.matrix([[1,2,3],[4,5,6]])
y=np.matrix([1,2,3,4,5,6])
# x[1,1]返回行下标和列下标都为1的元素
# 注意,对于矩阵x来说,x[1,1]和x[1][1]的含义不一样
print(x,y,x[1,1],sep='\n\n')
[[1 2 3]
 [4 5 6]]

[[1 2 3 4 5 6]]

5

2.2矩阵转置

x=np.matrix([[1,2,3],[4,5,6]])
y=np.matrix([1,2,3,4,5,6])
print(x.T, y.T, sep='\n\n')
[[1 4]
 [2 5]
 [3 6]]

[[1]
 [2]
 [3]
 [4]
 [5]
 [6]]

2.3查看矩阵特征

import numpy as np

x = np.matrix([[1,2,3], [4,5,6]])
print(x.mean(), end='\n====\n')             # 所有元素平均值
print(x.mean(axis=0), end='\n====\n')       # 纵向平均值
print(x.mean(axis=0).shape, end='\n====\n')
print(x.mean(axis=1), end='\n====\n')       # 横向平均值
print(x.sum(), end='\n====\n')              # 所有元素之和
print(x.max(axis=1), end='\n====\n')        # 横向最大值
print(x.argmax(axis=1), end='\n====\n')     # 横向最大值的下标
print(x.diagonal(), end='\n====\n')         # 对角线元素
print(x.nonzero())                 # 非0元素下标,分别返回行下标和列下标
3.5
====
[[2.5 3.5 4.5]]
====
(1, 3)
====
[[2.]
 [5.]]
====
21
====
[[3]
 [6]]
====
[[2]
 [2]]
====
[[1 5]]
====
(array([0, 0, 0, 1, 1, 1], dtype=int64), array([0, 1, 2, 0, 1, 2], dtype=int64))

2.4矩阵乘法

x=np.matrix([[1,2,3],[4,5,6]])
y=np.matrix([[1,2],[3,4],[5,6]])
print(x*y)
[[22 28]
 [49 64]]
x
matrix([[1, 2, 3],
        [4, 5, 6]])
y
matrix([[1, 2],
        [3, 4],
        [5, 6]])

2.5计算相关系数矩阵

import numpy as np

print(np.corrcoef([1,2,3,4], [4,3,2,1]))  #负相关,变化方向相反
print(np.corrcoef([1,2,3,4], [8,3,2,1]))  #负相关,变化方向相反
print(np.corrcoef([1,2,3,4], [1,2,3,4]))  #正相关,变化方向一致
print(np.corrcoef([1,2,3,4], [1,2,3,40])) #正相关,变化趋势接近
[[ 1. -1.]
 [-1.  1.]]
[[ 1.         -0.91350028]
 [-0.91350028  1.        ]]
[[1. 1.]
 [1. 1.]]
[[1.        0.8010362]
 [0.8010362 1.       ]]

2.6计算方差、协方差、标准差

import numpy as np

print(np.cov([1,1,1,1,1]))         # 方差
print(np.std([1,1,1,1,1]))         # 标准差
x = [-2.1, -1,  4.3]
y = [3,  1.1,  0.12]
X = np.vstack((x,y))               # 垂直堆叠矩阵
print(X)
print(np.cov(X))                   # 协方差
print(np.cov(x, y))
print(np.std(X))                   # 标准差
print(np.std(X, axis=1))
print(np.cov(x))                   # 方差
0.0
0.0
[[-2.1  -1.    4.3 ]
 [ 3.    1.1   0.12]]
[[11.71       -4.286     ]
 [-4.286       2.14413333]]
[[11.71       -4.286     ]
 [-4.286       2.14413333]]
2.2071223094538484
[2.79404128 1.19558447]
11.709999999999999

3计算特征值与特征向量

对于n×n方阵A,如果存在标量λ和n 维非0向量\(\overrightarrow{x}\),使得A·\(\overrightarrow{x}\)\(\overrightarrow{x}\)成立,那么称 λ 是方阵 A 的一个特征值,\(\overrightarrow{x}\)为对应于 λ 的特征向量。

从几何意义来讲,矩阵乘以一个向量,是对这个向量进行了一个变换,从一个坐标系变换到另一个坐标系。在变换过程中,向量主要发生旋转和缩放这两种变化。如果矩阵乘以一个向量之后,向量只发生了缩放变化而没有进行旋转,那么这个向量就是该矩阵的特征向量,缩放的比例就是特征值。或者说,特征向量是对数据进行旋转之后理想的坐标轴之一,而特征值则是该坐标轴上的投影或者贡献。特征值越大,表示这个坐标轴对原向量的表达越重要,原向量在这个坐标轴上的投影越大。一个矩阵的所有特征向量组成了该矩阵的一组基,也就是新坐标系中的轴。有了特征值和特征向量之后,向量就可以在另一个坐标系中进行表示。

import numpy as np

A = np.array([[1,-3,3],[3,-5,3], [6,-6,4]])
e, v = np.linalg.eig(A)                # 特征值与特征向量
print(e, v, sep='\n')
print(np.dot(A,v))                     # 矩阵与特征向量的乘积
print(e*v)                             # 特征值与特征向量的乘积
print(np.isclose(np.dot(A,v), e*v))    # 验证二者是否相等
# 行列式|A-λE|的值应为0,det()是计算行列式的函数
print(np.linalg.det(A-np.eye(3,3)*e))
[ 4. -2. -2.]
[[-0.40824829 -0.81034214  0.1932607 ]
 [-0.40824829 -0.31851537 -0.59038328]
 [-0.81649658  0.49182677 -0.78364398]]
[[-1.63299316  1.62068428 -0.38652141]
 [-1.63299316  0.63703074  1.18076655]
 [-3.26598632 -0.98365355  1.56728796]]
[[-1.63299316  1.62068428 -0.38652141]
 [-1.63299316  0.63703074  1.18076655]
 [-3.26598632 -0.98365355  1.56728796]]
[[ True  True  True]
 [ True  True  True]
 [ True  True  True]]
3.197442310920445e-14

4计算逆矩阵

import numpy as np

x = np.matrix([[1,2,3], [4,5,6], [7,8,0]])
y = np.linalg.inv(x)
print(y)
print(x*y)          # 对角线元素为1,其他元素为0或近似为0
print(y*x)
[[-1.77777778  0.88888889 -0.11111111]
 [ 1.55555556 -0.77777778  0.22222222]
 [-0.11111111  0.22222222 -0.11111111]]
[[ 1.00000000e+00  1.66533454e-16  1.38777878e-17]
 [-1.05471187e-15  1.00000000e+00  2.77555756e-17]
 [ 0.00000000e+00  0.00000000e+00  1.00000000e+00]]
[[ 1.00000000e+00 -4.44089210e-16  0.00000000e+00]
 [ 2.77555756e-16  1.00000000e+00  0.00000000e+00]
 [ 6.93889390e-17  1.11022302e-16  1.00000000e+00]]

5求解线性方程组

import numpy as np

a = np.array([[3,1], [1,2]])   # 系数矩阵
b = np.array([9,8])            # 系数矩阵
x = np.linalg.solve(a, b)      # 求解
print(x)
print(np.dot(a, x))            # 验证
print(np.linalg.lstsq(a, b))   # 最小二乘解
                               # 返回解、余项、a的秩、a的奇异值
[2. 3.]
[9. 8.]
(array([2., 3.]), array([], dtype=float64), 2, array([3.61803399, 1.38196601]))

6计算向量和矩阵的范数

在线性代数中,一个n维空间中的一个点,向量的长度称为模或2-范数。对于向量 (x1,x2,x3,…….,xn),其模长也就是向量与自己的内积的平方根,计算公式为:
image

向量p-范数计算公式为(其中p为不等于0的整数)

\[\|\vec{x}\|_p=\left(\sum_{i=1}^n\left|x_i\right|^p\right)^{1 / p} \]

对于m×n的矩阵A,常用的范数有Frobenius范数(也称F-范数),其计算公式为:

\[\|A\|_F=\sqrt{\sum_{i=1}^m \sum_{j=1}^n\left|a_{i j}\right|^2} \]

矩阵A的2-范数是矩阵A的共轭转置矩阵与A的乘积的最大特征值的平方根,其计算公式为:

\[\|A\|_2=\sqrt{\lambda_{A^H A}} \]

x=np.matrix([[1,2],[3,-4]])
print(np.linalg.norm(x))
5.477225575051661
print(np.linalg.norm(x,-2))
1.9543950758485487
print(np.linalg.norm(x,-1))
4.0
print(np.linalg.norm([1,2,0,3,4,0],0))
4.0
print(np.linalg.norm([1,2,0,3,4],2))
5.477225575051661

7奇异值分解

a=np.matrix([[1,2,3],[4,5,6],[7,8,9]])
u,s,v=np.linalg.svd(a)
u
matrix([[-0.21483724,  0.88723069,  0.40824829],
        [-0.52058739,  0.24964395, -0.81649658],
        [-0.82633754, -0.38794278,  0.40824829]])
s
array([1.68481034e+01, 1.06836951e+00, 3.33475287e-16])
v
matrix([[-0.47967118, -0.57236779, -0.66506441],
        [-0.77669099, -0.07568647,  0.62531805],
        [-0.40824829,  0.81649658, -0.40824829]])
u*np.diag(s)*v
matrix([[1., 2., 3.],
        [4., 5., 6.],
        [7., 8., 9.]])

8函数向量化

mat=np.matrix([[1,2,3],[4,5,6]])
mat
matrix([[1, 2, 3],
        [4, 5, 6]])
import math
a = math.factorial(4)
print(a)
24
vecFactorial=np.vectorize(math.factorial)#函数向量化
vecFactorial(mat)
matrix([[  1,   2,   6],
        [ 24, 120, 720]])
posted @ 2023-05-04 23:06  小平凡的记录  阅读(103)  评论(0编辑  收藏  举报