ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

NumPy中的矩阵运算函数小记

NumPy中的矩阵运算函数小记 前言先纠正标题里两个不严谨的地方。第一NumPy 不是 Python 标准库它是需要单独安装的第三方库用pip install numpy本机没装它所以下面的调用无法在本机运行验证API 签名均以 NumPy 官方文档为准请你以自己的环境为准。第二「矩阵运算函数」这个说法偏笼统——NumPy 里做矩阵运算的东西有三种形态模块级函数如numpy.dot、ndarray的方法如a.reshape(...)、以及运算符、*。把a b叫「函数」并不准确它是运算符背后调用__matmul__。另外要提前说清一个高频误解在 NumPy 里*是逐元素相乘element-wise也叫 Hadamard 积不是矩阵乘法矩阵乘法要用运算符或numpy.matmul/numpy.dot。大量「矩阵乘法算错了」的 bug根源就是把*当成了矩阵乘。再补一句版本提醒Python 2.7 已于 2020 年 1 月 1 日停止维护较新的 NumPy 也早已不再支持 Python 2网上老代码里的print语句print x、xrange等写法在 Python 3 里都不能用本文示例一律按 Python 3 写。本文按「建矩阵 → 改形状 → 做乘法 → 解线性方程组」的顺序记几种常用的矩阵运算写法并给出可对照官方的签名。一、创建矩阵与查看形状ndarray是 NumPy 的核心数据结构二维的ndarray就是通常说的矩阵。# 适用于 Python 3.8 且已安装 NumPy以官方文档为准import numpy as npA np.array([[1, 2], [3, 4]]) # 由嵌套列表构造 2x2Z np.zeros((2, 3)) # 2 行 3 列全 0默认 float64O np.ones((3, 3)) # 3x3 全 1I np.eye(3) # 3x3 单位矩阵print(A.shape) # (2, 2)print(A.dtype) # int64视平台而定print(Z.shape) # (2, 3)形状通过.shape属性读取它是一个元组。修改形状不会复制数据只要内存布局允许.reshape返回的是视图view。# 适用于 Python 3.8 且已安装 NumPy以官方文档为准a np.arange(6) # 一维 [0 1 2 3 4 5]m np.reshape(a, (2, 3)) # 变成 2x3print(m.shape) # (2, 3)print(a.shape) # (6,) ← 原数组不变二、转置.T与numpy.transpose转置有两种等价写法数组属性.T或函数numpy.transpose(a, axesNone)。# 适用于 Python 3.8 且已安装 NumPy以官方文档为准A np.array([[1, 2, 3], [4, 5, 6]])print(A.shape) # (2, 3)print(A.T.shape) # (3, 2)print(np.transpose(A).shape) # (3, 2)官方文档特别指出对一维数组transpose返回的是原数组的一个未改动视图——一维没有「行列」可换。要留意多维数组的转置在三维及以上默认是「反转所有轴的顺序」需要更精细控制时才传axes。三、矩阵乘法、matmul、dot三种写法写法官方签名 / 说明A B运算符等价于调用__matmul__Python 3.5 起支持PEP 465numpy.matmul(x1, x2, /, outNone, *, castingsame_kind, orderK, dtypeNone, subokTrue)函数形式官方推荐numpy.dot(a, b, outNone)老的通用函数文档注明「using matmul or a b is preferred」A * B逐元素相乘不是矩阵乘对两个二维数组、matmul、dot结果一致# 适用于 Python 3.8 且已安装 NumPy以官方文档为准A np.array([[1, 2], [3, 4]])B np.array([[5, 6], [7, 8]])print(A * B)# [[ 5 12]# [21 32]] ← 逐元素相乘print(A B)# [[19 22]# [43 50]] ← 矩阵乘法print(np.matmul(A, B)) # 与 A B 相同print(np.dot(A, B)) # 二维时也与 A B 相同验算A B第一行第一列1*5 2*7 19对得上A * B第一行第一列是1*5 5也就是逐元素。matmul和dot的差异在两处一是matmul不接受标量dot可以二是维数大于 2 时matmul把数组当成「一批矩阵」并按广播规则处理dot则是把a的最后一个轴与b的倒数第二个轴求和。日常二维矩阵用哪个都行但官方推荐matmul或。四、线性代数numpy.linalg矩阵求逆、行列式、解方程都在numpy.linalg里签名如下均以官方文档为准函数签名作用numpy.linalg.invinv(a)求逆矩阵numpy.linalg.detdet(a)求行列式numpy.linalg.solvesolve(a, b)解线性方程组a x bnumpy.linalg.eigeig(a)求特征值与特征向量# 适用于 Python 3.8 且已安装 NumPy以官方文档为准import numpy as npA np.array([[3.0, 1.0], [1.0, 2.0]])print(np.linalg.det(A)) # 5.0 3*2 - 1*1inv_A np.linalg.inv(A)print(np.allclose(A inv_A, np.eye(2))) # True ← 用 allclose 查浮点近似相等b np.array([9.0, 8.0])x np.linalg.solve(A, b)print(x) # [2. 3.]print(np.allclose(A x, b)) # True要点np.linalg.inv要求矩阵是方阵否则抛LinAlgError若矩阵奇异不可逆同样抛LinAlgError。解方程组优先用np.linalg.solve(A, b)而不是先求逆再乘inv(A) b——后者数值上更不稳定也更慢。判断浮点结果是否相等不要用用numpy.allclose(a, b, rtol1e-05, atol1e-08, equal_nanFalse)。实战解一个线性方程组下面是一个完整的小例子解A x b再回代验证。# 适用于 Python 3.8 且已安装 NumPy以官方文档为准import numpy as npdef solve_system(A, b):解 A x b返回解向量奇异或非方阵时抛 numpy.linalg.LinAlgError。A np.asarray(A, dtypefloat)b np.asarray(b, dtypefloat)x np.linalg.solve(A, b)ok np.allclose(A x, b)return x, okif __name__ __main__:A [[2, 1, -1],[-3, -1, 2],[-2, 1, 2]]b [8, -11, -3]x, ok solve_system(A, b)print(解, x) # 解 [ 2. 3. -1.]print(验证, ok) # 验证 True逐行说明np.asarray(...)把列表转成数组dtypefloat保证后续按浮点运算避免整数下整除问题。np.linalg.solve直接得到未知数向量x没有显式求逆。np.allclose(A x, b)把结果代回验证浮点误差在你的容差范围内就返回True。常见坑点把*当矩阵乘法❌C A * B想做矩阵乘法 —— 得到的其实是逐元素积。 ✅ 矩阵乘用C A B或np.matmul(A, B)。先求逆再乘 b 解方程❌x np.linalg.inv(A) b—— 数值稳定性差、更慢。 ✅x np.linalg.solve(A, b)。浮点结果用比较❌if A x b:—— 浮点误差导致偶尔为假。 ✅if np.allclose(A x, b):。对非方阵求逆❌ 对 2x3 矩阵调np.linalg.inv—— 抛numpy.linalg.LinAlgError。 ✅ 确认矩阵是方阵非方阵要解方程用最小二乘之类的其他方法。误以为reshape会复制数据❌b a.reshape(2, 3)后改b以为a不受影响 —— 若返回的是视图两者共享底层数据。 ✅ 需要独立副本就显式b a.reshape(2, 3).copy()。用numpy.matrix写线性代数❌ 用np.matrix构造矩阵 —— 官方文档明确「It is no longer recommended to use this class, even for linear algebra. Instead use regular arrays.」且该类未来可能被移除。 ✅ 用二维ndarray加运算符。在没装 NumPy 的环境里 import❌import numpy后直接用 —— 未安装会ModuleNotFoundError: No module named numpy。 ✅ 先pip install numpy并在代码里用try/except ImportError给出友好提示如果面向他人分发。整数数组下的除法❌ 用整数类型的数组做平均期望得到小数 —— 若走的是整除语义会截断。 ✅ 构造时指定dtypefloat或用/得到浮点结果/在 Python 3 和 NumPy 里都是真除法整除要写//。总结目的写法备注构造矩阵np.array、np.zeros、np.ones、np.eye二维ndarray形状 / 转置.shape、.reshape、.T、np.transposereshape常返回视图矩阵乘法A B、np.matmul(A, B)官方推荐np.dot亦可逐元素乘A * B不是矩阵乘法求逆 / 行列式np.linalg.inv、np.linalg.det需方阵奇异抛LinAlgError解方程np.linalg.solve(A, b)优于先求逆浮点比较np.allclose别用NumPy 的矩阵运算记起来不复杂乘法认准*只管逐元素线性代数进numpy.linalg结果比较用allclose再避开np.matrix这个已被官方劝退的老类。由于 NumPy 是第三方库且版本演进较快实际使用时请以你所用版本的官方文档为准。
返回列表