一.多维矩阵乘法
NumPy 是 Python 中最基础也是最重要的科学计算库之一,它提供了高性能的多维数组对象和各种数学函数。
python
'''
矩阵乘法:
使用 np.dot(A, B) 和 A @ B 两种方法进行矩阵乘法。
标量与矩阵相乘:
将标量 2 与矩阵 A 相乘。
矩阵与向量乘法:
将矩阵 A 与列向量 v 相乘。
广播机制下的矩阵乘法:
将标量 3 与矩阵 A 相乘,NumPy 会自动进行广播操作。
其他线代运算:
转置矩阵:使用 A.T 获得矩阵 A 的转置。
逆矩阵:使用 np.linalg.inv(A) 获得矩阵 A 的逆矩阵。
行列式:使用 np.linalg.det(A) 获得矩阵 A 的行列式。
特征值分解:使用 np.linalg.eig(A) 获得矩阵 A 的特征值和特征向量。
'''
python
import numpy as np
# 1. 数组创建
arr = np.array([1, 2, 3]) # 一维数组
arr2d = np.array([[1, 2], [3, 4]]) # 二维数组
zeros = np.zeros((3, 4)) # 创建全零数组
ones = np.ones((2, 2)) # 创建全一数组
arange = np.arange(0, 10, 2) # 创建等差数列
linspace = np.linspace(0, 10, 5) # 创建等间隔数值
# 2. 数组属性
print("数组维度:", arr.ndim)
print("数组形状:", arr.shape)
print("数组数据类型:", arr.dtype)
print("数组大小:", arr.size)
# 3. 数组操作
arr_add = arr + 5 # 元素加法
arr_mult = arr * 2 # 元素乘法
concatenate = np.concatenate((arr, [4, 5])) # 数组合并
# 4. 常用数学函数
sin_arr = np.sin(arr) # 正弦函数
exp_arr = np.exp(arr) # e的幂函数
sqrt_arr = np.sqrt(arr) # 开方函数
# 5. 文件读写
np.save('my_array.npy', arr) # 保存数组
loaded_arr = np.load('my_array.npy') # 加载数组
python
import numpy as np
# 创建两个矩阵
A = np.array([[1, 2],
[3, 4]])
B = np.array([[5, 6],
[7, 8]])
# ------------矩阵乘法---------------
print("------------矩阵乘法---------------")
# 方法1:使用 dot() 进行矩阵乘法
result = np.dot(A, B)
print('\n方法1:使用 dot() 进行矩阵乘法:\n {}'.format(result))
# 方法2:使用 @ 运算符进行矩阵乘法
result = A @ B
print('\n方法2:使用 @ 运算符进行矩阵乘法:\n {}'.format(result))
# ------------标量与矩阵相乘---------------
print("\n------------标量与矩阵相乘---------------\n")
scalar = 2
result = scalar * A
print("矩阵为:\n{}\n标量数乘为:\n{}".format(A, result))
# ------------矩阵与向量乘法---------------
print("\n------------矩阵与向量乘法---------------\n")
v = np.array([3, 4]) # 创建列向量(二维数组)
result = A @ v # 矩阵乘以向量
print("矩阵为:\n{}\n列向量为:\n{}\n矩阵与向量乘法:\n{}".format(A, v, result))
# ------------广播机制下的矩阵乘法---------------
print("\n------------广播机制下的矩阵乘法---------------\n")
# 矩阵乘法会与标量或向量结合,NumPy 会自动进行"广播"操作
scalar = 3 # 创建一个标量
result = A * scalar # 标量乘法
print("矩阵为:\n{}\n标量为:\n{}\n广播机制下的矩阵乘法:\n{}".format(A, scalar, result))
# ------------其他运算---------------
print("\n------------其他线代运算1:转置矩阵---------------\n")
T = A.T
print('矩阵为:\n{}\n转置矩阵为:\n {}'.format(A, T))
print("\n------------其他线代运算2:逆矩阵---------------\n")
N = np.linalg.inv(A) # 修正:传入矩阵 A
print('矩阵为:\n{}\n矩阵逆为:\n {}'.format(A, N))
print("\n------------其他线代运算3:行列式---------------\n")
H = np.linalg.det(A) # 修正:传入矩阵 A
print('矩阵为:\n{}\n行列式为:\n {}'.format(A, H))
print("\n------------其他线代运算4:特征值分解---------------\n")
Z = np.linalg.eig(A) # 修正:传入矩阵 A
print('矩阵为:\n{}\n特征值分解为:\n {}'.format(A, Z))
二.矩阵运算的高级使用
python
'''
在学习深度学习框架,或者准备做数据分析项目,需要了解矩阵运算的性能优化技巧。
明确几个核心方向:向量化操作、广播机制、内存布局、并行计算。这些都是提升矩阵运算效率的关键点。
向量化操作:使用 NumPy 提供的函数来代替显式的循环。
广播机制:允许不同形状的数组进行算术运算。
内存布局:了解数组在内存中的存储方式,优化访问模式。
并行计算:使用并行计算库(如 Numba 或 Dask)来加速计算。
'''
import numpy as np
'''向量化操作是指使用 NumPy 等库提供的函数来代替显式的循环操作。
向量化操作通常比显式的循环更快,因为它们在底层使用了优化的 C 或 Fortran 代码。'''
# 创建两个数组
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = a + b # 向量化操作
print('矩阵1为:\n{}\n矩阵2为:\n {}\n向量化操作结果:\n{}'.format(a,b,c))
'''广播机制允许不同形状的数组进行算术运算。NumPy 会自动扩展较小的数组,使其与较大的数组具有相同的形状。'''
# 创建一个二维数组和一个一维数组
a1 = np.array([[1, 2, 3], [4, 5, 6]])
b1 = np.array([10, 20, 30])
c1 = a1 + b1 # 广播机制
print('矩阵1为:\n{}\n矩阵2为:\n {}\n广播机制结果:\n{}'.format(a1,b1,c1))
'''内存布局对性能有重要影响,可以帮助优化代码。NumPy 数组在内存中是连续存储的,这使得某些操作(如按行或按列访问)更高效。'''
# 创建一个二维数组
A = np.array([[1, 2, 3], [4, 5, 6]])
# 检查内存布局
print("数组A:\n{}\n数组的内存布局:\n{}".format(A,A.flags))
'''并行计算可以显著提高矩阵运算的效率,NumPy 本身在某些操作中已经使用了并行计算,也可以使用其他库(如 Numba 或 Dask)来进一步优化。'''
import numpy as np
import numba
# 定义一个使用 Numba 的并行函数
@numba.jit(nopython=True, parallel=True)
def parallel_sum(A, B):
return A + B
# 创建两个大数组
A = np.random.rand(10000, 10000)
B = np.random.rand(10000, 10000)
# 使用并行计算
C = parallel_sum(A, B)
print("并行计算结果:", C[0, 0])
python
'''有更加高效的写法:避免中间变量,减少内存拷贝,运行后对比'''
import numpy as np
import numba
import time
# 定义一个使用 Numba 的并行函数
@numba.jit(nopython=True, parallel=True)
def parallel_sum(A, B):
return A + B
# 更高效写法:避免中间变量,减少内存拷贝
# 定义一个手动指定循环的并行函数
@numba.jit(nopython=True, parallel=True)
def fast_add(A, B, C):
for i in numba.prange(A.shape[0]):
for j in range(A.shape[1]):
C[i, j] = A[i, j] + B[i, j]
return C
# 创建两个大数组
A = np.random.rand(10000, 10000)
B = np.random.rand(10000, 10000)
C = np.empty_like(A)
# 使用并行计算
start_time = time.time()
C1 = parallel_sum(A, B)
parallel_sum_time = time.time() - start_time
print("使用Numba并行计算结果 (parallel_sum):", C1[0, 0])
print("使用Numba并行计算时间 (parallel_sum):", parallel_sum_time, "秒")
# 使用手动指定循环的并行计算
start_time = time.time()
C2 = fast_add(A, B, C)
fast_add_time = time.time() - start_time
print("手动指定循环并行计算结果 (fast_add):", C2[0, 0])
print("手动指定循环并行计算时间 (fast_add):", fast_add_time, "秒")
print("\n对比后 手动指定循环并行计算时间(fast_add)比使用Numba并行计算时间(parallel_sum):\n快了\t{}秒".format(parallel_sum_time-fast_add_time))
整理不易,诚望各位看官点赞 收藏 评论 予以支持,这将成为我持续更新的动力源泉。若您在阅览时存有异议或建议,敬请留言指正批评,让我们携手共同学习,共同进取,吾辈自当相互勉励!