Numpy(2) 矩阵

  Numpy函数库中存在两种不同的数据类型(矩阵matrix和数组array),数组中的元素可以是字符等,矩阵中的只能是数,这是二者最直观的区别。

1 mat( )函数和array( )函数的区别

  mat()函数将目标数据的类型转化成矩阵(matrix)。二者都可以用于处理行列表示的数字元素,虽然他们看起来很相似,但是在这两个数据类型上执行相同的数学运算可能得到不同的结果。

  (1)mat( ) 函数与array( )函数生成矩阵所需的数据格式有区别,mat()函数中数据可以为字符串以分号(;)分割或者为列表形式以逗号(,)分割,而array()函数中数据只能为后者形式。  

import numpy as np
a = np.mat('1 3 ; 5 7')
b = np.mat([[1, 2], [3, 4]])
c = np.array([[1, 3], [4, 5]])
print(a)
print(type(a))
print(b)
print(c)
print(type(c))

# [[1 3]
#  [5 7]]
# <class 'numpy.matrix'>
# [[1 2]
#  [3 4]]
# [[1 3]
#  [4 5]]
# <class 'numpy.ndarray'>

  (2)两者的类型不同,用mat函数转换为矩阵后才能进行一些线性代数的操作。

arr1 = np.random.rand(4, 4)
mat1 = np.mat(arr1)
print(arr1.I)   # 'numpy.ndarray' object has no attribute 'I'
print(mat1.I)

2 矩阵创建

  (1)通过mat( )函数将字符串、列表、数组、随机数转换为矩阵

  (2)通过eye( )函数和diag( )函数生成特殊矩阵

a1 = [1, 2, 3]
a2 = np.mat(np.diag(a1))    # 生成一个对角线为1,2,3的对角矩阵
print(a2)
# [[1 0 0]
#  [0 2 0]
#  [0 0 3]]
a3 = np.mat(np.eye(2, 2, dtype=int))    # 产生一个2*2的对角矩阵
print(a3)
# [[1 0]
#  [0 1]]

3 常见的矩阵运算

  (1)矩阵乘(*):要求左边矩阵的列和右边矩阵的行数要一致

a1 = np.mat([1, 2])
print(a1.shape)     # (1, 2)
a2 = np.mat([[1], [2]])
print(a2.shape)     # (2, 1)
a3 = a1 * a2
print(a3)   # [[5]]

  (2)矩阵点乘(multiply):要求矩阵必须维数相等,即M*N维矩阵乘以M*N维矩阵,当矩阵点乘常数时,会先通过广播机制将常数扩展为与矩阵维度相等的矩阵再进行操作。

a1 = np.mat([3, 5])
print(a1.shape)     # (1, 2)
a2 = np.mat([4, 8])
print(a2.shape)     # (1, 2)
a3 = np.multiply(a1, a2)
print(a3)   # [[12 40]]
a4 = 9      
print(np.multiply(a1, a4))      # [[27 45]] 此处用到了广播机制

  (3)矩阵求逆(.I):每个元素取倒数

a1 = np.mat(np.eye(2, 2)*0.5)
print(a1)
# [[0.5 0. ]
#  [0.  0.5]]
a2 = a1.I
print(a2)
# [[2. 0.]
#  [0. 2.]]

  (4)矩阵转置(.T):变换维度

a1 = np.mat([[1, 2, 3], [4, 5, 6]])
print(a1.shape)     # (2, 3)
a2 = a1.T
print(a2.shape)     # (3, 2)

  (5)求和:sum

a1 = np.mat([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print('===== 原矩阵 =====')
print(a1)
a2 = np.sum(a1, axis=0)     # 按列求和
a3 = np.sum(a1, axis=1)     # 按行求和
a4 = np.sum(a1)     # 矩阵所有元素和
a5 = np.sum(a1[1:])  # 指定行求和(所有列元素相加)
a6 = np.sum(a1[:1])  # 指定列求和(所有行元素相加)
print('===== 按列求和 =====')
print(a2)
print('===== 按行求和 =====')
print(a3)
print('===== 矩阵所有元素和 =====')
print(a4)
print('===== 指定行求和 =====')
print(a5)
print('===== 指定列求和 =====')
print(a6)
# ===== 原矩阵 ===== # [[1 2 3] # [4 5 6] # [7 8 9]] # ===== 按列求和 ===== # [[12 15 18]] # ===== 按行求和 ===== # [[ 6] # [15] # [24]] # ===== 矩阵所有元素和 ===== # 45 # ===== 指定行求和 ===== # 39 # ===== 指定列求和 ===== # 6

  (6)求最大值、最小值及对应索引(元素位置):max、min、argmax、argmin

a1 = np.mat([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
a2 = np.max(a1, axis=0)
idx_max = np.argmax(a1, axis=0)
a3 = np.min(a1, axis=1)
idx_min = np.argmin(a1, axis=0)
print('===== 所有列的最大值 =====')
print(a2)
print('===== 所有列的最大值对用索引 =====')
print(idx_max)
print('===== 所有列的最小值 =====')
print(a3)
print('===== 所有列的最小值对用索引 =====')
print(idx_min)

# ===== 所有列的最大值 =====
# [[7 8 9]]
# ===== 所有列的最大值对用索引 =====
# [[2 2 2]]
# ===== 所有列的最小值 =====
# [[1]
#  [4]
#  [7]]
# ===== 所有列的最小值对用索引 =====
# [[0 0 0]]

4 矩阵分割与合并

  矩阵的分割,同列表和数组的分割一致;矩阵合并要求被操作的矩阵形状相同(所有维度数量必须一致)。

a = np.mat(np.ones((2, 2)))
print(a.shape)      # (2, 2)
b = np.mat(np.eye(2))
print(b.shape)      # (2, 2)
c = np.vstack((a, b))   # 按照列和并,即增加行数
print(c.shape)      # (4, 2)
d = np.hstack((a, b))   # 按照行合并,即行数不变,扩展列数
print(d.shape)      # (2, 4)

5 矩阵、数组、列表转换

  5.1 三者的区别

  (1)列表中元素可以是不同类型的数据;

  (2)数组中的元素必须为同一个类型;

  (3)矩阵中的元素必须为数值型,同时具有数组属性(shape、ndim、size、dtype)

  5.2 具体转换

  (1)列表转换

a1 = [1, 2, 3]
print(a1, type(a1))     # [1, 2, 3] <class 'list'>
a2 = np.array(a1)
print(a2, type(a2))     # [1 2 3] <class 'numpy.ndarray'>
a3 = np.mat(a1)
print(a3, type(a3))     # [[1 2 3]] <class 'numpy.matrix'>

  (2)数组转换

a4 = a2.tolist()
print(a4, type(a4))     # [1, 2, 3] <class 'list'>
a5 = np.mat(a2)
print(a5, type(a5))     # [[1 2 3]] <class 'numpy.matrix'>

  (3)矩阵转换

a6 = a3.tolist()
print(a6, type(a6))     # [[1, 2, 3]] <class 'list'>    与a1有区别
a7 = np.array(a3)
print(a7, type(a7))     # [[1 2 3]] <class 'numpy.ndarray'>     与a2有区别

  注意:当列表是一维的时候,将它转换成数组和矩阵后,再通过tolist()转换成列表是不相同的。

猜你喜欢

转载自www.cnblogs.com/wisefaith/p/12354251.html