python教程(一):超详细的numpy矩阵操作和运算(附实例代码)

在Python中,numpy提供了强大的矩阵运算功能。使用numpy,你可以轻松执行矩阵加法、矩阵乘法、转置、逆矩阵、行列式等多种矩阵运算。而在机器学习、深度学习和自动驾驶算法开发中,矩阵运算是最基础的运算,本文详细介绍numpy的矩阵操作和运算方法,同时通过实例展示其在具体工程开发中的应用。

1. 矩阵创建

1.1 普通矩阵

通过 numpy.array() 将 Python 的二维列表转换为 NumPy 矩阵。

import numpy as np

# 使用二维列表创建一个 2x3 的矩阵
matrix = np.array([[1, 2, 3], [4, 5, 6]])

print(matrix)

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

1.2 特殊矩阵

1.2.1 全零矩阵

使用 numpy.zeros() 创建一个全零矩阵,指定矩阵的形状即可。

# 创建一个 3x3 的全零矩阵
zero_matrix = np.zeros((3, 3))

 1.2.2 全1矩阵

使用 numpy.ones() 创建一个所有元素为1的矩阵。

# 创建一个 2x2 的全1矩阵
ones_matrix = np.ones((2, 2))

 1.2.3 单位矩阵

使用 numpy.eye()numpy.identity() 创建单位矩阵。单位矩阵是对角线为1,其余元素为0的方阵。

# 创建一个 3x3 的单位矩阵
identity_matrix = np.eye(3)

 1.2.4 随机矩阵

使用 numpy.random.rand() 创建一个指定形状的随机矩阵,元素的取值范围在 [0, 1) 之间。

# 创建一个 2x3 的随机矩阵
random_matrix = np.random.rand(2, 3)

 1.2.5 随机整数矩阵

使用 numpy.random.randint() 创建一个由随机整数组成的矩阵,指定取值范围和矩阵形状。

# 创建一个 2x3 的随机整数矩阵,元素在 [0, 10) 之间
random_int_matrix = np.random.randint(0, 10, size=(2, 3))

 1.2.6 特定范围的矩阵

使用 numpy.arange()reshape() 创建一个包含特定范围数值的矩阵,

# 创建一个包含 1 到 9 的矩阵,并 reshape 为 3x3 的矩阵
# numpy.arange(start, stop, step, dtype=None)默认不包括终点

range_matrix = np.arange(1, 10, 1).reshape((3, 3))

 1.2.7 等间隔数值矩阵

使用 numpy.linspace() 创建一个包含等间隔数值的矩阵。

# 创建包含从 0 到 1 的 9 个等间隔数值的数组
# numpy.linspace(start, stop, num=50)默认包括终点

linspace_matrix = np.linspace(1, 9, 9).reshape((3, 3))

 1.2.8 对角矩阵

使用 numpy.diag() 可以从一个数组生成对角矩阵,或者提取矩阵的对角线元素。

# 创建一个对角矩阵
diag_matrix = np.diag([1, 2, 3])

2. 矩阵array参数

ndim:返回数组的维数

shape:返回数组的形状

size:返回数组中所有元素的总个数

dtype:返回数组中元素的数据类型

itemsize:返回数组中每个元素的字节大小

nbytes:返回数组占用的总字节数

import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])

print("维度 (ndim):", arr.ndim)
print("形状 (shape):", arr.shape)
print("元素总数 (size):", arr.size)
print("数据类型 (dtype):", arr.dtype)
print("每个元素的字节大小 (itemsize):", arr.itemsize)
print("数组占用的总字节大小 (nbytes):", arr.nbytes)

3. 矩阵索引

NumPy 中,矩阵(多维数组)的索引和切片非常灵活,可以通过多种方式访问或修改矩阵中的元素。以下是一些常见的 NumPy 矩阵索引操作。

3.1 基本索引

与 Python 的列表类似,NumPy 矩阵的索引从 0 开始,可以使用行、列的索引来访问特定元素。

import numpy as np

# 创建一个 3x3 矩阵
A = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])

# 访问第一行第二列的元素
element = A[0, 1]
print("第一行第二列的元素:", element)

3.2 矩阵切片

切片操作可以用于选择矩阵中的一部分。语法为 [起始:结束:步长]

# 选择前两行的所有列
row_slice = A[:2, :]
print("前两行的子矩阵:\n", row_slice)

# 选择所有行的第二列
col_slice = A[:, 1]
print("所有行的第二列:\n", col_slice)

# 选择前两行和前两列
sub_matrix = A[:2, :2]
print("子矩阵:\n", sub_matrix)

# 选择所有行,每隔一列取一个元素
step_slice = A[:, ::2]
print("步长为2的子矩阵:\n", step_slice)

3.3 布尔索引

布尔索引允许通过条件筛选矩阵中的元素,返回满足条件的元素。

# 选择矩阵中所有大于5的元素
bool_index = A[A > 5]
print("大于5的元素:", bool_index)

3.4 花式索引

花式索引允许通过指定多个索引来访问矩阵中的特定元素。

# 访问矩阵中指定的行和列的元素
fancy_index = A[[0, 2], [1, 2]]  # 访问 (0,1) 和 (2,2) 位置的元素
print("花式索引结果:", fancy_index)

3.5 子矩阵索引

可以通过使用多个索引列表选择特定的行和列组成子矩阵。

# 选择第 0 和 2 行,第 1 和 2 列,生成子矩阵
sub_matrix = A[[0, 2], :][:, [1, 2]]
print("子矩阵:\n", sub_matrix)

4. 矩阵拼接

NumPy 中,矩阵拼接(合并)操作主要通过 numpy.concatenate()numpy.hstack()numpy.vstack()numpy.stack() 等函数来实现。可以通过这些函数将多个矩阵沿不同的轴进行拼接。

4.1 numpy.concatenate

numpy.concatenate() 可以将多个数组沿指定的轴进行拼接。默认情况下,它沿着第一个轴(axis=0)拼接。numpy.vstack()numpy.concatenate() 的简化版,用于垂直方向(沿 axis=0,行)的拼接,相当于 axis=0 的拼接。

import numpy as np

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 沿着 axis=0 拼接(即行拼接)
C = np.concatenate((A, B), axis=0)
print("行拼接结果:\n", C)

D = np.concatenate((A, B), axis=1)
print("列拼接结果:\n", D)

E = np.vstack((A, B))
print("垂直拼接结果:\n", E)

F = np.hstack((A, B))
print("水平拼接结果:\n", F)

4.2 numpy.stack

numpy.stack() 是用于沿着新轴拼接数组,它可以在现有的数组中插入一个新的维度进行拼接。你可以指定 axis 参数来选择在哪个轴上插入新的维度。

G = np.stack((A, B), axis=0)
print("沿新轴拼接结果(axis=0):\n", G)

沿新轴拼接结果(axis=0):
 [[[1 2]
   [3 4]]

  [[5 6]
   [7 8]]]

4.3 numpy.block

numpy.block() 函数可以用于更复杂的矩阵拼接,通过提供嵌套列表的方式将多个矩阵块组合成一个大的矩阵。

K = np.block([[A, B], [B, A]])
print("块拼接结果:\n", K)

5. 矩阵初级运算

5.1 矩阵逐元素加减乘除

矩阵逐元素加减乘除是逐元素操作,要求两个矩阵的形状相同。

import numpy as np

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 矩阵加法
C = A + B
print("矩阵加法:\n", C)

# 矩阵减法
D = A - B
print("矩阵减法:\n", D)

# 矩阵逐元素乘法
element_wise_product = A * B
print("逐元素乘法:\n", element_wise_product)

# 矩阵逐元素除法
element_wise_divide = A / B
print("逐元素除法结果:\n", element_wise_divide)

5.2 矩阵乘法

矩阵点乘:矩阵对应元素相乘(形状相同)np.multiply(a,b) 或a*b

矩阵叉乘(矩阵相乘):np.dot(a,b)或a@b

向量点乘(向量内积):np.dot(a,b)或a@b,为标量

向量逐元素相乘:np.multiply(a,b)等价于a*b

向量外积(向量积或叉积):np.cross(a,b)两个向量的法向量

import numpy as np

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
C = np.array([1, 2, 3])
D = np.array([5, 6, 7])

# 矩阵点乘/矩阵逐元素相乘
E = A * B
F = np.multiply(A, B)



# 矩阵相乘/矩阵叉乘
G = A @ B
H = np.dot(A, B)


# 向量点乘/向量内积
J = C @ D
K = np.dot(C, D)


# 向量逐元素相乘
L = C * D
M = np.multiply(C, D)


# 向量外积、向量积或叉积,向量的法向量
N = np.cross(C, D)
print("向量外积:\n", N)

6. 矩阵的高级操作

6.1 矩阵属性

矩阵转置:矩阵的转置是将矩阵的行和列互换,使用 .T 属性。

矩阵的逆:矩阵的逆对方阵(行数与列数相同的矩阵)定义,使用 numpy.linalg.inv() 可以计算矩阵的逆。

矩阵的行列式:行列式是标量值,表示矩阵的某些属性(如是否可逆)。使用 numpy.linalg.det() 可以计算矩阵的行列式。

矩阵的迹:矩阵的迹是矩阵主对角线上元素的和,使用 numpy.trace() 可以计算。

矩阵的特征值和特征向量:特征值和特征向量是矩阵的重要属性。你可以使用 numpy.linalg.eig() 函数来计算特征值和特征向量。

矩阵的广义逆:广义逆矩阵(Moore-Penrose伪逆)用于非方阵或不可逆的矩阵。使用 numpy.linalg.pinv() 计算矩阵的广义逆。

矩阵的范数:矩阵的范数用于度量矩阵的大小。可以使用 numpy.linalg.norm() 计算不同类型的范数。

import numpy as np

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 矩阵转置
A_T = A.T
print("矩阵转置:\n", A_T)

# 矩阵的逆
A_inv = np.linalg.inv(A)
print("矩阵的逆:\n", A_inv)

# 矩阵的行列式
det_A = np.linalg.det(A)
print("矩阵行列式:\n", det_A)

# 矩阵的迹
trace_A = np.trace(A)
print("矩阵的迹:\n", trace_A)

# 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)
print("特征值:\n", eigenvalues)
print("特征向量:\n", eigenvectors)

# 计算广义逆矩阵
pseudo_inv = np.linalg.pinv(A)
print("广义逆矩阵:\n", pseudo_inv)


# 计算矩阵的二范数(默认)
norm_A = np.linalg.norm(A)
print("矩阵的二范数:\n", norm_A)

# 计算矩阵的 1 范数(列和的最大值)
norm_A_1 = np.linalg.norm(A, ord=1)
print("矩阵的 1 范数:\n", norm_A_1)

# 计算矩阵的无穷范数(行和的最大值)
norm_A_inf = np.linalg.norm(A, ord=np.inf)
print("矩阵的无穷范数:\n", norm_A_inf)

6.2 广播机制

广播机制允许对不同形状的数组执行逐元素操作,NumPy 会自动扩展较小的数组以匹配较大的数组进行计算。广播使得矩阵运算更加高效和简洁。

import numpy as np

# 2x3 的矩阵
A = np.array([[1, 2, 3], [4, 5, 6]])

# 1x3 的数组,广播到 2x3 的形状
B = np.array([10, 20, 30])

# 逐元素相加
C = A + B
print("广播后的矩阵相加结果:\n", C)

6.3 矩阵分解

矩阵分解是线性代数中的重要工具,常用于求解线性方程组、特征值问题、最小二乘法等。NumPy 提供了多种矩阵分解方法,如 LU 分解、QR 分解和奇异值分解(SVD)。

6.3.1 LU 分解

LU 分解将矩阵分解为一个下三角矩阵和一个上三角矩阵。

import scipy.linalg as la

A = np.array([[4, 3], [6, 3]])
P, L, U = la.lu(A)

print("P 矩阵:\n", P)
print("L 矩阵:\n", L)
print("U 矩阵:\n", U)

6.3.2 QR 分解

QR 分解将矩阵分解为正交矩阵和上三角矩阵。

Q, R = np.linalg.qr(A)
print("Q 矩阵:\n", Q)
print("R 矩阵:\n", R)

6.3.3 SVD分解

SVD 是将矩阵分解为三个矩阵:左奇异矩阵、对角矩阵(奇异值)、右奇异矩阵。

U, S, V = np.linalg.svd(A)
print("U 矩阵:\n", U)
print("奇异值:\n", S)
print("V 矩阵:\n", V)

6.4 最小二乘法

使用 numpy.linalg.lstsq() 解决超定方程(方程个数多于未知数)的最小二乘问题。

import numpy as np

A = np.array([[1, 1], [1, 2], [1, 3]])
B = np.array([1, 2, 2])

# 使用最小二乘法求解 AX = B
X, residuals, rank, s = np.linalg.lstsq(A, B, rcond=None)
print("最小二乘法求解结果:\n", X)

7. 张量计算

7.1 张量定义

NumPy 中,张量是指具有多维数据结构的数组,通常扩展自二维矩阵。张量可以是 1D(向量)、2D(矩阵)、3D(例如彩色图像的表示)甚至是更高维度的数组。NumPy 提供了多种方法来操作和计算张量,广泛应用于机器学习、深度学习、科学计算等领域。在 NumPy 中,张量本质上就是多维数组,使用 np.array() 函数可以创建不同维度的张量。

7.2 张量运算

7.2.1 numpy.tensordot

numpy.tensordot() 是用于计算两个张量的 张量积。它可以沿指定的轴对两个张量进行求和操作。这种方法常用于执行类似矩阵乘法或高维张量的积操作。你可以指定沿哪些轴进行运算。

import numpy as np

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

C = np.tensordot(A, B, axes=1)
print("矩阵乘法结果(tensordot):\n", C)

7.2.2 numpy.einsum

numpy.einsum() 实现了基于 爱因斯坦求和约定(Einstein Summation Convention) 的张量运算。它允许通过字符来表示张量的维度,并定义如何操作张量(求和、外积、内积、转置、矩阵乘法等)。这种方式提供了更灵活和简洁的表达方式,适用于各种张量运算。

import numpy as np

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 使用 einsum 进行矩阵乘法
C = np.einsum('ik,kj->ij', A, B)
print("矩阵乘法结果:\n", C)


diagonal = np.einsum('ii->i', A)
print("矩阵的对角线元素:", diagonal)


trace = np.einsum('ii->', A)
print("矩阵的迹:", trace)

8. 应用示例

8.1 解3x3线性方程组

考虑线性方程组:\begin{cases} x + 2y + 3z = 1 \\ 4x + 5y + 6z = 2 \\ 7x + 4y + 3z = 3 \end{cases}

对应的矩阵形式为:

  • A = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 4 & 3 \end{bmatrix}

  • B = \begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix}

使用 numpy.linalg.solve() 来求解:

import numpy as np

# 系数矩阵 A
A = np.array([[1, 2, 3], [4, 5, 6], [7, 4, 3]])

# 结果向量 B
B = np.array([1, 2, 3])

# 求解线性方程组
X = np.linalg.solve(A, B)
print("解:\n", X)

 解:
 [ 1.         -2.          1.33333333]

8.2 二次多项式拟合

假设我们有一组数据点,拟合一条二次曲线y = ax^2 + bx + c

import numpy as np
import matplotlib.pyplot as plt

# 给定的 x 和 y 数据
x = np.array([0, 1, 2, 3, 4, 5])
y = np.array([1, 1.8, 3.2, 4.5, 6.1, 8])

# 使用 numpy.polyfit 拟合二次多项式
coefficients = np.polyfit(x, y, 2)

# 打印拟合的多项式系数
print("二次多项式系数:", coefficients)

# 根据拟合结果创建多项式函数
p = np.poly1d(coefficients)

# 生成拟合曲线的 x 和 y 值
x_fit = np.linspace(0, 5, 100)
y_fit = p(x_fit)

# 绘制原始数据点和拟合曲线
plt.scatter(x, y, color='red', label='数据点')
plt.plot(x_fit, y_fit, label='拟合曲线', color='blue')
plt.xlabel('x')
plt.ylabel('y')
plt.title('二次多项式拟合')
plt.legend()
plt.show()

 二次多项式系数: [0.1125     0.84321429 0.96071429]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值