当前位置:首页>python>我的Python100天打卡:69 用爱因斯坦求和约定做数组转置、矩阵乘法

我的Python100天打卡:69 用爱因斯坦求和约定做数组转置、矩阵乘法

  • 2026-10-11 08:42:38
我的Python100天打卡:69 用爱因斯坦求和约定做数组转置、矩阵乘法

#鸢尾花数学大系

挑战100天持续练习Python
今天是第69天

上次笔记,完成了第十八章Numpy关于爱因斯坦求和约定的基础学习。这是一个极其强大且简洁的工具,可以用一种统一的语法完成数组的求和、转置、乘法等操作,可理解为线性代数与张量运算的瑞士军刀。

今天的学习内容,继续深入探索Numpy的“爱因斯坦求和约定”,包括:

18.3 二维、三维数组转置

18.4 矩阵乘法(格拉姆矩阵、分类矩阵乘法)

--
爱因斯坦求和约定(Einstein summation convention)是一种数学记号,用于简化张量运算中的求和符号。NumPy中的np.einsum函数通过一个字符串公式指定操作,可以替代许多显式循环和特定函数。
# 代码18.1 利用爱因斯坦求和约定求和import numpy as npfrom sklearn.datasets import load_iris# 加载鸢尾花数据集iris = load_iris()X = iris.data  # 形状 (150, 4)y = iris.target# 每一列求和:等价于 np.sum(X, axis=0)col_sum = np.einsum('ij->j', X)# 字符串'ij->j'含义:#   - 输入X有两个维度:i(行)、j(列)#   - 输出只保留j维度,对i维度求和(压缩i)#   - 结果是一维数组,长度为4(列数)# 每一行求和:等价于 np.sum(X, axis=1)row_sum = np.einsum('ij->i', X)# 'ij->i':压缩j维度,保留i维度# 所有元素求和:等价于 np.sum(X, axis=(0,1)) 或 np.sum(X)total_sum = np.einsum('ij->', X)# 'ij->':压缩所有维度,输出标量图示辅助理解
--
18.3 转置二维、三维数组
-
18.3.1 二维数组转置
1️⃣用np.einsum()来转置二维数组的关键代码,特别简洁。书本中也提到,可以用np.transpose()来进行数组的转置操作。
# 代码18.2 利用爱因斯坦求和约定完成转置# 二维数组转置:等价于 X.T 或 np.transpose(X)X_T = np.einsum('ij->ji', X)# 'ij->ji':调换输入的两个维度索引
2️⃣图18.5展示了以上代码的二维数组转置的直观过程,其核心是矩阵的行列互换。
-
18.3.2 三维数组转置
三维或更高维数组可以自由指定维度的交换顺序。
1️⃣图18.6展现的是三维数组的转置,保持i不变,通过调换维度j和k,完成这两个方向的转置。
也可以这样理解:维度索引从 (i, j, k) 变为 (i, k, j),相当于在每个“切片”内进行二维转置。
2️⃣相关代码和注释:
# 首先创建一个三维数组,例如将三类鸢尾花数据堆叠X_setosa = X[y == 0]  # 第一类样本X_versicolor = X[y == 1]X_virginica = X[y == 2]X_3d = np.stack([X_setosa, X_versicolor, X_virginica])  # 形状 (3, 50, 4)# 三维数组转置:保持第一个维度不变,交换后两个维度X_transposed = np.einsum('ijk->ikj', X_3d)# 等价于 np.transpose(X_3d, (0, 2, 1))
--
18.4 矩阵乘法格拉姆矩阵
1️⃣格拉姆矩阵是列向量的内积矩阵,在机器学习中常用于度量特征间的相关性。
# 计算格拉姆矩阵 G = X^T XG = np.einsum('ij,ik->jk', X, X)# 等价于 X.T @ X# 字符串'ij,ik->jk'含义:#   - 第一个输入X维度为(i,j),第二个输入X维度为(i,k)#   - 输出维度为(j,k),对公共维度i求和
2️⃣图18.7展示了计算格拉姆矩阵时维度索引的折叠过程:公共维度i(样本数)被求和(或者说被“压缩”掉了),得到形状为(j,k)的方阵。
3️⃣图18.8解释了:
1,格拉姆矩阵对角线元素,是每个特征的平方和
2,格拉姆矩阵非对角线元素,是不同特征的内积。
4️⃣另一种格拉姆矩阵形式是H = X X^T,度量样本之间的相似性:
H = np.einsum('ij,kj->ik', X, X)
# 等价于 X @ X.T
图18.9展示了计算H的时候,维度j的折叠。
--
18.3.3 分类矩阵乘法
1️⃣根据不同类别,分别计算格拉姆矩阵,可以用于分类任务中的度量学习。
# 假设我们有一个类别标签向量y,想对每个类别分别计算格拉姆矩阵# 这里以三类鸢尾花为例,X_3d形状(3, 50, 4)代表三类样本# 对每个类别切片计算格拉姆矩阵G_per_class = np.einsum('bij,bik->bjk', X_3d, X_3d)# 字符串'bij,bik->bjk':#   - b: 类别维度,i: 样本维度,j/k: 特征维度#   - 对每个类别b,计算其内部样本i的格拉姆矩阵# 结果形状(3, 4, 4),即每个类别一个4x4的格拉姆矩阵
2️⃣图18.10展示了考虑类别时,维度索引的复杂组合。
3️⃣代码18.3及其相关注释:
4️⃣关键代码及通俗解释:
三维转置的关键代码:
G_3D = np.einsum('ijk,ijm->ikm', X3D, X3D)
↑ 要说我懂不懂,我肯定是……不懂的!
于是求助AI编程教练解释:
答案是ijk, ijm -> jkm。
---
心得体会
1. einsum非常强大。用统一的语法,统一的函数,集中处理求和、转置、乘法、张量收缩等操作,直观高效,降低记忆负担。
2. einsum在数据科学和机器学习中的应用:
(1)特征统计:快速计算均值、方差、协方差矩阵
(2)主成分分析:计算协方差矩阵、特征值分解。
(3)神经网络:张量运算(如卷积、注意力机制)常用einsum实现。
(4)物理模拟:处理高阶张量(应力、应变等)的合约运算。
爱因斯坦求和约定初看抽象,但一旦掌握,将成为处理多维数组的利器。它让我们以更接近数学表达的方式编写代码,提高生产力和代码可读性。

---

笔记写于:2026年4月29日13:04:29

结束于:2026年4月29日13:55

用时:约50分钟

--

#鸢尾花数学大系

#编程随记

最新文章

随机文章