首页 > 人工智能 > 人工智能 > 人工智能之数据分析 numpy:第九章 数组运算
第九章 数组运算
NumPy 不仅提供了高效的多维数组(
ndarray)结构,还内置了丰富的
数组运算功能,包括基础算术、比较逻辑、位运算、通用函数(ufunc)、矩阵与线性代数等。这些运算是
向量化的,无需显式循环,性能远超纯 Python。
下面系统讲解 NumPy 的各类数组运算。
NumPy 支持对数组进行 逐元素(element-wise) 的四则运算和幂运算。
import numpy as np a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) print(a + b) # [5 7 9] print(a - b) # [-3 -3 -3] print(a * b) # [4 10 18] print(a / b) # [0.25 0.4 0.5 ] print(a ** 2) # [1 4 9] print(a % 2) # [1 0 1]
# 标量与数组运算 print(a + 10) # [11 12 13] # 不同形状但兼容的数组 A = np.array([[1, 2, 3], [4, 5, 6]]) # shape (2,3) B = np.array([10, 20, 30]) # shape (3,) print(A + B) # [[11 22 33] # [14 25 36]] ← B 被广播到每一行
✅ 广播规则:从后往前对齐维度,缺失或为1的维度可扩展。
返回布尔数组,常用于筛选。
a = np.array([1, 2, 3, 4]) b = np.array([1, 3, 2, 4]) print(a == b) # [ True False False True] print(a != b) # [False True True False] print(a > 2) # [False False True True] print(np.equal(a, b)) # 等价于 a == b
# 找出三个数组中相等的位置 c = np.array([1, 3, 3, 4]) mask = (a == b) & (b == c) print(mask) # [ True False True True]
适用于布尔数组。
| 运算 | 函数 | 说明 |
|
|---|---|---|---|
| 与 |
np.logical_and(x, y) 或
x & y |
元素级 AND |
|
| 或 |
np.logical_or(x, y) 或 `x \ |
y` | 元素级 OR |
| 非 |
np.logical_not(x) 或
~x |
元素级 NOT |
|
| 异或 |
np.logical_xor(x, y) |
XOR |
|
x = np.array([True, False, True]) y = np.array([True, True, False]) print(x & y) # [ True False False] print(np.logical_and(x, y)) # 同上 print(~x) # [False True False]
⚠️ 注意:对非布尔数组使用
&,|会执行 位运算(见下文),而非逻辑运算!
对整数类型的二进制位进行操作。
| 运算符 | 函数 | 说明 |
|
|---|---|---|---|
& |
np.bitwise_and |
按位与 |
|
| `\ | ` |
np.bitwise_or |
按位或 |
^ |
np.bitwise_xor |
按位异或 |
|
~ |
np.invert |
按位取反 |
|
<< |
np.left_shift |
左移 |
|
>> |
np.right_shift |
右移 |
|
a = np.array([1, 2, 3]) # 二进制: 01, 10, 11 b = np.array([3, 2, 1]) # 11, 10, 01 print(a & b) # [1 2 1] → 01&11=01, 10&10=10, 11&01=01 print(a << 1) # [2 4 6] → 左移1位(×2)
💡 位运算常用于掩码操作、图像处理、嵌入式系统等。
ufunc 是 NumPy 的核心,提供 向量化、快速、元素级的数学函数。
x = np.array([0, np.pi/2, np.pi]) print(np.sin(x)) # [0.0, 1.0, ~0.0] print(np.cos(x)) # [1.0, ~0.0, -1.0] print(np.exp(x)) # [1.0, ~4.81, ~23.14] print(np.log([1, np.e, np.e**2])) # [0. 1. 2.] print(np.sqrt([4, 9, 16])) # [2. 3. 4.]
a = np.array([1, 2, 3, 4]) print(np.add.reduce(a)) # 10(求和) print(np.multiply.reduce(a))# 24(连乘) print(np.add.accumulate(a)) # [1 3 6 10](前缀和)
# 将普通函数转为 ufunc def my_func(x, y): return x**2 + y**2 my_ufunc = np.frompyfunc(my_func, 2, 1) result = my_ufunc([1, 2], [3, 4]) # 返回 object 数组
⚠️
frompyfunc性能较低,仅用于无法向量化的场景。
numpy.linalg)在 NumPy 中, 矩阵(Matrix) 有两种主要表示方式:
ndarray(推荐方式)np.matrix 类下面将详细讲解这两种方式,并重点说明
为什么现代 NumPy 推荐使用
ndarray 而非
matrix,以及如何高效进行矩阵运算。
np.matrix:历史遗留(已弃用)import numpy as np
# 从字符串、列表或 ndarray 创建
M = np.matrix([[1, 2], [3, 4]])
N = np.matrix('1 2; 3 4') # 字符串形式
print(M)
# [[1 2]
# [3 4]]
* 表示矩阵乘法(不是逐元素相乘).I(逆)、
.T(转置)等属性A = np.matrix([[1, 2], [3, 4]]) B = np.matrix([[5, 6], [7, 8]]) print(A * B) # 矩阵乘法! # [[19 22] # [43 50]] print(A.I) # 逆矩阵 print(A.T) # 转置
ndarray 混用时容易出错📌 官方建议: 不要使用
np.matrix,改用ndarray+@运算符。
ndarray 表示矩阵A = np.array([[1, 2], [3, 4]]) # shape: (2, 2) B = np.arange(1, 5).reshape(2, 2) # [[1 2] # [3 4]]
| 操作 | 推荐写法 | 说明 |
| ----------------------- | --------------------------------- | ------------------------- |
|
矩阵乘法 |
A @ B 或
np.dot(A, B) | Python 3.5+ 支持
@ |
|
逐元素乘法 |
A * B | 默认行为 |
|
转置 |
A.T 或
A.transpose() | |
|
逆矩阵 |
np.linalg.inv(A) | |
|
行列式 |
np.linalg.det(A) | |
|
解方程 Ax=b |
np.linalg.solve(A, b) | |
A = np.array([[1, 2],
[3, 4]], dtype=float)
B = np.array([[5, 6],
[7, 8]], dtype=float)
# 矩阵乘法
C = A @ B
print("A @ B =\n", C)
# 转置
print("A.T =\n", A.T)
# 逆矩阵
A_inv = np.linalg.inv(A)
print("A⁻¹ =\n", A_inv)
print("A @ A⁻¹ ≈ I:\n", A @ A_inv) # 应接近单位矩阵
# 解线性方程组
b = np.array([5, 11])
x = np.linalg.solve(A, b)
print("Solution x =", x) # [1. 2.] → 1*1+2*2=5, 3*1+4*2=11
输出:
A @ B = [[19. 22.] [43. 50.]] A.T = [[1. 3.] [2. 4.]] A⁻¹ = [[-2. 1. ] [ 1.5 -0.5]] A @ A⁻¹ ≈ I: [[1.0000000e+00 0.0000000e+00] [8.8817842e-16 1.0000000e+00]] Solution x = [1. 2.]
ndarray)M = np.array([[1, 2, 3], [4, 5, 6]]) print(M.ndim) # 2 print(M.shape) # (2, 3) print(M.size) # 6
# 零矩阵 Z = np.zeros((3, 3)) # 单位矩阵 I = np.eye(3) # 或 np.identity(3) # 对角矩阵 D = np.diag([1, 2, 3]) # 随机矩阵 R = np.random.rand(2, 2)
numpy.linalg)A = np.array([[1, 2], [3, 4]], dtype=float) # 特征值分解 eigenvals, eigenvecs = np.linalg.eig(A) # 奇异值分解 (SVD) U, s, Vt = np.linalg.svd(A) # QR 分解 Q, R = np.linalg.qr(A)
# L2 范数(谱范数) norm_A = np.linalg.norm(A, 2) # Frobenius 范数 fro_norm = np.linalg.norm(A, 'fro') # 条件数 cond_num = np.linalg.cond(A)
A = np.random.rand(3, 4) B = np.random.rand(4, 2) C = A @ B # ✅ (3,4) @ (4,2) → (3,2) # D = A @ A # ❌ (3,4) @ (3,4) → 维度不匹配!
A = np.array([[1, 2], [3, 4]]) v = np.array([1, 2]) # shape: (2,) —— 一维向量 # 左乘:v^T A → 结果是行向量(一维) result1 = v @ A # [7, 10] # 右乘:A v → 结果是列向量(一维) result2 = A @ v # [5, 11] # 若需显式列向量,用 reshape v_col = v.reshape(-1, 1) # shape: (2, 1) Av = A @ v_col # shape: (2, 1)
💡 NumPy 中的一维数组在矩阵乘法中 自动视为行或列向量,非常灵活。
# 数据:X (n_samples, n_features), y (n_samples,)
X = np.array([[1, 1],
[1, 2],
[1, 3]]) # 添加偏置项
y = np.array([2, 3, 4])
# 正规方程:w = (X^T X)^{-1} X^T y
XTX_inv = np.linalg.inv(X.T @ X)
w = XTX_inv @ X.T @ y
print("Weights:", w) # [1. 1.] → y = 1 + 1*x
theta = np.pi / 4 # 45度
R = np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]]) # 旋转矩阵
point = np.array([1, 0]) # x轴上的点
rotated = R @ point
print("Rotated point:", rotated) # [0.707, 0.707]
| 项目 | 推荐做法 |
|---|---|
| 数据结构 | 使用
np.array(二维),
不要用
np.matrix |
| 矩阵乘法 | 用
@ 或
np.dot() |
| 转置 | 用
.T |
| 逆矩阵 | 用
np.linalg.inv() |
| 解方程 | 用
np.linalg.solve()(比求逆更稳定高效) |
| 高维张量 |
ndarray 支持任意维度,
matrix 不支持 |
🔑 核心理念: 统一使用
ndarray,通过@和linalg模块完成所有矩阵运算,代码更清晰、兼容性更好、性能更优。
np.linalg)NumPy 通过
np.dot 和
numpy.linalg 模块支持线性代数运算。
| 函数 | 说明 |
|---|---|
np.linalg.inv(A) |
矩阵求逆 |
np.linalg.det(A) |
行列式 |
np.linalg.eig(A) |
特征值与特征向量 |
np.linalg.solve(A, b) |
解线性方程组 Ax = b |
np.linalg.norm(x) |
向量/矩阵范数(默认 L2) |
np.linalg.svd(A) |
奇异值分解 |
# 2x + y = 5 # x + 3y = 10 A = np.array([[2, 1], [1, 3]]) b = np.array([5, 10]) x = np.linalg.solve(A, b) print(x) # [1. 3.] → x=1, y=3
norm = np.linalg.norm(A, 'fro') # 或默认 ord=None
arr = np.array([[1, 2, 3], [4, 5, 6]]) print(arr.sum()) # 21 print(arr.sum(axis=0)) # [5 7 9](按列求和) print(arr.mean(axis=1)) # [2. 5.](每行均值) print(np.std(arr)) # 标准差 print(np.max(arr)) # 最大值
x = np.array([1.234, 2.567, 3.891]) print(np.round(x, 1)) # [1.2 2.6 3.9] print(np.floor(x)) # [1. 2. 3.] print(np.ceil(x)) # [2. 3. 4.]
| 类型 | 示例函数/运算符 | 说明 |
|
|---|---|---|---|
| 算术 |
+ - * / ** % |
逐元素运算,支持广播 |
|
| 比较 |
== != > < >= <= |
返回布尔数组 |
|
| 逻辑 | `& \ | ~`(布尔数组) | 逻辑与/或/非 |
| 位运算 | `& \ | ^ ~ << >>`(整数) | 二进制位操作 |
| ufunc |
np.sin,
np.exp,
np.sqrt |
向量化数学函数 |
|
| 矩阵乘法 |
@,
np.dot |
线性代数乘法 |
|
| 线性代数 |
np.linalg.inv,
solve,
eig |
高级矩阵运算 |
|
| 聚合 |
sum,
mean,
std,
max |
沿轴归约 |
|
* 与
@:A * B:逐元素相乘A @ B:矩阵乘法``
python a = np.array([1, 2]) b = np.array([[1], [2]]) print(a + b) # shape (2,2) —— 小心意外广播! ``
``
python x = np.array([200], dtype=np.uint8) print(x * 2) # 144(200*2=400 → 溢出回绕) ``
``
python np.seterr(divide='ignore', invalid='ignore') # 控制警告行为 ``
本文主要讲述了numpy数组相关的运算。python过渡项目部分代码已经上传至gitee,后续会逐步更新,主要受时间原因限制,当然自己也可以克隆到本地学习拓展。
公众号:咚咚王 gitee: https://gitee.com/wy18585051844/ai_learning

《Python编程:从入门到实践》 《利用Python进行数据分析》 《算法导论中文第三版》 《概率论与数理统计(第四版) (盛骤) 》 《程序员的数学》 《线性代数应该这样学第3版》 《微积分和数学分析引论》 《(西瓜书)周志华-机器学习》 《TensorFlow机器学习实战指南》 《Sklearn与TensorFlow机器学习实用指南》 《模式识别(第四版)》 《深度学习 deep learning》伊恩·古德费洛著 花书 《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》 《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》 《自然语言处理综论 第2版》 《Natural-Language-Processing-with-PyTorch》 《计算机视觉-算法与应用(中文版)》 《Learning OpenCV 4》 《AIGC:智能创作时代》杜雨+&+张孜铭 《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》 《从零构建大语言模型(中文版)》 《实战AI大模型》 《AI 3.0》
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048224/viewspace-3103059/ ,如需转载,请注明出处,否则将追究法律责任。