Numpy中einsum函数用法

  • 一、一维张量收缩
  • 二、二维张量收缩
    • 2.1 收缩到零维张量
    • 2.2 收缩到一维张量
  • 三、三维张量收缩(重难点)
    • 3.1 例1
    • 3.2 例2
  • 四、其他功能介绍(次要)
    • 功能一:求矩阵的迹
    • 功能二:取对角元素
    • 功能三 :对某个维度求和
    • 功能四:矩阵转置
    • 功能五:矩阵或向量的内积
    • 功能六:矩阵和向量乘法
    • 功能七:向量外积

【导读】 einsum全称Einstein summation convention(爱因斯坦求和约定),又称为爱因斯坦标记法。能够计算任何维度的张量收缩。einsum的写法省去了求和符号,显得更加简洁。

一、一维张量收缩

对于一维张量,也即向量(Vector)。其收缩为零维张量,也即标量(Scalar):

c=∑iaibic =\sum_i a_i b_ic=i∑​ai​bi​所以einsum 的写法就是:
c=aibic= a_i b_ic=ai​bi​用代码表示为:

>>> a = np.arange(10)
>>> b = np.arange(10)+1
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
>>> np.einsum('i,i', a, b)
330

二、二维张量收缩

同样对于二维张量,也即矩阵(Matrix)。其收缩为一维张量或零维张量:

2.1 收缩到零维张量

c=aijaij=∑i,jaijaijc=a_{ij }a_{ij}= \sum_{i,j} a_{ij }a_{ij}c=aij​aij​=i,j∑​aij​aij​也即求矩阵内积

array([[0, 1],[2, 3],[4, 5]])
>>> np.einsum('ij,ij', a, b)
70

2.2 收缩到一维张量

ci=∑jAijBijc_i = \sum_j A_{ij} B_{ij}ci​=j∑​Aij​Bij​或cj=∑iAijBijc_j = \sum_i A_{ij} B_{ij}cj​=i∑​Aij​Bij​
其中,cic_ici​为两矩阵对应位置元素相乘后再把列元素相加;cjc_jcj​为两矩阵对应位置元素相乘后把行相加

>>> np.einsum('ij,ij->i', a, b)
array([ 8, 62])
>>> np.einsum('ij,ij->j', a, b)
array([12, 22, 36])

再给出一个例子

>>> a1 = np.array([[0,1],[2,3],[4,5]])
>>> a1
array([[0, 1],[2, 3],[4, 5]])
>>> np.einsum('ji,ij->i', a1, a)
array([10, 40])

再给出一个矩阵与向量的例子

>>> a2 = np.array([[1,2],[3,4],[5,6]])
>>> b2 = np.array([1,2])
>
>>> np.einsum('ij,j', a2, b2)
array([ 5, 11, 17])
>>> np.einsum('ij,j->...', a2, b2)    # 收缩到零维
33

再给出一个多个向量的例子

>>> c2 = np.array([1,2,3])
>>> np.einsum('ij,j,i->i', a2, b2, c2)
array([ 5, 22, 51])
>>> np.einsum('ij,j,i->...', a2, b2, c2)  # 收缩到零维
78

三、三维张量收缩(重难点)

由于其组合非常多样,如三维张量与矩阵、向量的爱因斯坦求和运算,收缩到二维、一维、零维,我们不一一讨论。这里我们只给出三维张量之间进行爱因斯坦求和、收缩到二维张量的例子

3.1 例1

>>> a = np.arange(6).reshape(1,2,3)
>>> b = np.arange(24).reshape(2,3,4)
>>> a
array([[[0, 1, 2],[3, 4, 5]]])
>>> b
array([[[ 0,  1,  2,  3],[ 4,  5,  6,  7],[ 8,  9, 10, 11]],[[12, 13, 14, 15],[16, 17, 18, 19],[20, 21, 22, 23]]])>>> np.einsum('ijk,jkl->il', a, b)
array([[220, 235, 250, 265]])

其中,i=1,j=2,k=3,l=4i=1\;,j=2\;,k=3\;,l=4i=1,j=2,k=3,l=4,可知会产生1×41\times41×4的二维张量(矩阵)。
由公式:
Ci,l=aijkbjkl=∑j=01∑k=02aijkbjklC_{i,l} = a_{ijk}b_{jkl}=\sum_{j=0}^1 \sum_{k=0}^2a_{ijk}b_{jkl}Ci,l​=aijk​bjkl​=j=0∑1​k=0∑2​aijk​bjkl​
不失一般性,我们验证:C0,0=220C_{0,0} =220C0,0​=220
C0,0=a000∗b000+a001∗b010+a002∗b020+a010∗b100+a011∗b110+a012∗b120\begin{aligned}C_{0,0}=a_{000}*b_{000}+a_{001}*b_{010}+a_{002}*b_{020}\\+a_{010}*b_{100}+a_{011}*b_{110}+a_{012}*b_{120}\end{aligned}C0,0​=a000​∗b000​+a001​∗b010​+a002​∗b020​+a010​∗b100​+a011​∗b110​+a012​∗b120​​

C0,0=0∗0+1∗4+2∗8+3∗12+4∗16+5∗20=220C_{0,0}=0*0+1*4+2*8+3*12+4*16+5*20=220C0,0​=0∗0+1∗4+2∗8+3∗12+4∗16+5∗20=220
矩阵形式的计算过程:
[012][01234567891011]=[20232629]\begin{bmatrix}0&1&2\end{bmatrix}\begin{bmatrix} 0&1&2&3\\4&5&6&7\\8&9&10&11\end{bmatrix}=\begin{bmatrix}20&23&26&29\end{bmatrix}[0​1​2​]⎣⎡​048​159​2610​3711​⎦⎤​=[20​23​26​29​]
[345][121314151617181920212223]=[200212224236]\begin{bmatrix}3&4&5\end{bmatrix}\begin{bmatrix} 12&13&14&15\\16&17&18&19\\20&21&22&23\end{bmatrix}=\begin{bmatrix}200&212&224& 236\end{bmatrix}[3​4​5​]⎣⎡​121620​131721​141822​151923​⎦⎤​=[200​212​224​236​]

[220235250265]=[2023269]+[200212224236]\begin{bmatrix}220&235&250&265\end{bmatrix} =\begin{bmatrix}20&23&26&9\end{bmatrix} +\begin{bmatrix}200&212&224& 236\end{bmatrix}[220​235​250​265​]=[20​23​26​9​]+[200​212​224​236​]
对于更高维的张量收缩或大规模张量,不方便再用矩阵表示计算过程表示,建议直接由公式计算相关元素。

再给出一个复杂的例子:

3.2 例2

>>> a = np.arange(60.).reshape(3,4,5)
>>> b = np.arange(24.).reshape(4,3,2)
>>> np.einsum('ijk,jil->kl', a, b)
array([[4400., 4730.],[4532., 4874.],[4664., 5018.],[4796., 5162.],[4928., 5306.]])
>>> np.einsum(a, [0,1,2], b, [1,0,3], [2,3])   # 掌握上一种形式就好
array([[4400., 4730.],[4532., 4874.],[4664., 5018.],[4796., 5162.],[4928., 5306.]])

该例中i=3,j=4,k=5,l=2i=3\;,j=4\;,k=5\;,l=2i=3,j=4,k=5,l=2,可知会产生5×25\times25×2的二维张量
由公式:
Ck,l=aijkbjil=∑i=02∑j=03aijkbjilC_{k,l} = a_{ijk}b_{jil}=\sum_{i=0}^2 \sum_{j=0}^3a_{ijk}b_{jil}Ck,l​=aijk​bjil​=i=0∑2​j=0∑3​aijk​bjil​
同样,不失一般性验证C0,0=4400C_{0,0}=4400C0,0​=4400
C0,0=a000∗b000+a010∗b100+a020∗b200+a030∗b300+a100∗b010+a110∗b110+a120∗b210+a130∗b310+a200∗b020+a210∗b120+a220∗b220+a230∗b320\begin{aligned}C_{0,0}=a_{000}*b_{000}+a_{010}*b_{100}+a_{020}*b_{200}+a_{030}*b_{300}\\+a_{100}*b_{010}+a_{110}*b_{110}+a_{120}*b_{210}+a_{130}*b_{310}\\+a_{200}*b_{020}+a_{210}*b_{120}+a_{220}*b_{220}+a_{230}*b_{320}\end{aligned}C0,0​=a000​∗b000​+a010​∗b100​+a020​∗b200​+a030​∗b300​+a100​∗b010​+a110​∗b110​+a120​∗b210​+a130​∗b310​+a200​∗b020​+a210​∗b120​+a220​∗b220​+a230​∗b320​​
也即
C0,0=0∗0+5∗6+10∗12+15∗18+20∗2+25∗8+30∗14+35∗20+40∗4+45∗10+50∗16+55∗22=4400\begin{aligned}C_{0,0} &=0*0+5*6+10*12+15*18\\&+20*2+25*8+30*14+35*20\\&+40*4+45*10+50*16+55*22\\&=4400\end{aligned}C0,0​​=0∗0+5∗6+10∗12+15∗18+20∗2+25∗8+30∗14+35∗20+40∗4+45∗10+50∗16+55∗22=4400​

四、其他功能介绍(次要)

功能一:求矩阵的迹

 >>> a = np.arange(25).reshape(5,5)>>> a>>> array([[ 0,  1,  2,  3,  4],[ 5,  6,  7,  8,  9],[10, 11, 12, 13, 14],[15, 16, 17, 18, 19],[20, 21, 22, 23, 24]])>>> b = np.arange(5)>>> barray([0, 1, 2, 3, 4])>>> c = np.arange(6).reshape(2,3)>>> carray([[0, 1, 2],[3, 4, 5]])Trace of a matrix:>>> np.einsum('ii', a)60>>> np.einsum(a, [0,0])60>>> np.trace(a)60

功能二:取对角元素

Extract the diagonal (requires explicit form):>>> np.einsum('ii->i', a)array([ 0,  6, 12, 18, 24])>>> np.einsum(a, [0,0], [0])array([ 0,  6, 12, 18, 24])>>> np.diag(a)array([ 0,  6, 12, 18, 24])

功能三 :对某个维度求和

  Sum over an axis (requires explicit form):>>> np.einsum('ij->i', a)array([ 10,  35,  60,  85, 110])>>> np.einsum(a, [0,1], [0])array([ 10,  35,  60,  85, 110])>>> np.sum(a, axis=1)array([ 10,  35,  60,  85, 110])

对于更高维度的矩阵,对某一维度求和可以使用省略号

>>> a = np.arange(27).reshape(3,3,3)
>>> a
array([[[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8]],[[ 9, 10, 11],[12, 13, 14],[15, 16, 17]],[[18, 19, 20],[21, 22, 23],[24, 25, 26]]])
>>> np.einsum('...j->...', a)
array([[ 3, 12, 21],[30, 39, 48],[57, 66, 75]])

功能四:矩阵转置

>>> c = np.arange(6).reshape(2,3)
>>> c
array([[0, 1, 2],[3, 4, 5]])
>>> np.einsum('ji', c)
array([[0, 3],[1, 4],[2, 5]])
>>>
>>> np.einsum('ij->ji', c)
array([[0, 3],[1, 4],[2, 5]])
>>> np.einsum(c, [1,0])
array([[0, 3],[1, 4],[2, 5]])
>>> np.transpose(c)
array([[0, 3],[1, 4],[2, 5]])

功能五:矩阵或向量的内积

>>> b = np.arange(5)
>>> b
array([0, 1, 2, 3, 4])
>>> np.einsum('i,i', b, b)30
>>> np.einsum(b, [0], b, [0])30
>>> np.inner(b,b)30

功能六:矩阵和向量乘法

>>> a = np.arange(6).reshape(2,3)
>>> a
array([[0, 1, 2],[3, 4, 5]])
>>> b = np.arange(3)
>>> b
array([0, 1, 2])
>>> np.einsum('ij,j', a, b)
array([ 5, 14])
>>> np.dot(a,b)
array([ 5, 14])

为减少不必要的重复,接下来代码中不再说明同样功能的其他函数或enisum函数的另一种使用形式
如:

>>> np.einsum('...j->...', a)
array([ 3, 12])
>>> np.einsum(a, [Ellipsis,1], [Ellipsis])
array([ 3, 12])

功能七:向量外积

>>> a
array([0, 1, 2])
>>>
>>> b
array([1, 2, 3])
>>> np.einsum('i,j', a, b)
array([[0, 0, 0],[1, 2, 3],[2, 4, 6]])

Numpy库中einsum函数用法相关推荐

  1. Py之Numpy:Numpy库中常用函数的简介、应用之详细攻略

    Py之Numpy:Numpy库中常用函数的简介.应用之详细攻略 目录 Numpy库中常用函数的简介.应用 1.X, Y = np.meshgrid(X, Y) 相关文章 Py之Numpy:Numpy库 ...

  2. [转载] Python里面numpy库中zeros()的一些问题

    参考链接: Python中的numpy.zeros Python里面numpy库中zeros函数的一些问题 定义 本文记录了在使用numpy库中的zeros函数时遇到的一些问题 定义 用法:zeros ...

  3. python中mean的用法_python 的numpy库中的mean()函数用法介绍

    1. mean() 函数定义: numpy.mean(a, axis=None, dtype=None, out=None, keepdims=)[source] Compute the arithm ...

  4. Python:Numpy库中的invert()函数的用法

    Numpy库中的invert()函数的用法 官方解释: Compute bit-wise inversion, or bit-wise NOT, element-wise. Computes the ...

  5. python 的numpy库中的mean()函数用法介绍

    这篇文章主要介绍了python 的numpy库中的mean()函数用法介绍,具有很好对参考价值,希望对大家有所帮助.一起跟随小编过来看看吧 mean() 函数定义: 2 mean()函数功能: 求取均 ...

  6. python average函数怎么用_python 的numpy库中的mean()函数用法介绍

    1. mean() 函数定义: numpy.mean(a, axis=None, dtype=None, out=None, keepdims=)[source] Compute the arithm ...

  7. Python:numpy库中的一些函数简介、使用方法之详细攻略

    Python:numpy库中的一些函数简介.使用方法之详细攻略 目录 numpy库中的一些函数简介.使用方法 1.np.concatenate() 1.1.函数案例 1.2.函数用法 numpy库中的 ...

  8. Python的numpy库中rand(),randn(),randint(),random_integers()等random系函数的使用

    在使用Python进行数据处理时,往往需要用到大量的随机数据,那如何构造这么多数据呢?Python的第三方库numpy库中提供了random函数来实现这个功能. 本文将根据官方文档以及其他博友的博客一 ...

  9. python numpy库中省略号...的一些用法

    在学习<Designing Machine Learning Systems with Python>(<机器学习系统设计Python语言实现>)一书的第五章梯度下降一节代码中 ...

最新文章

  1. 机器人控制算法——Bayes Filter贝叶斯滤波器
  2. python小学_小学生学python(二)
  3. 识别不了socket未知的名称或服务
  4. CV之Hog+HamMingDistance:基于Hog提取和汉明距离对比的应用—图像相似度对比之for循环将多个成对图片依次对比并输出相似度
  5. 201671010406 丁家辉《英文文本统计分析》结对项目报告
  6. RHEL5.3下MRTG+SNMP的搭建
  7. leetcode - 1143. 最长公共子序列
  8. 文本编辑软件哪个好_过年倒计时软件哪个好 过年倒计时软件推荐
  9. Eclipse常用的一些设置
  10. RM2016视觉开源OpenCv2代码
  11. mbedtls交换服务器证书,mbedtls | 07 - DH秘钥协商算法的配置与使用
  12. java 处理 barCode(条形码)
  13. linux中c语言kbhit函数用法,检测按键(Linux中kbhit()函数的实现)
  14. 京东口罩到货,邮件实时通知
  15. STM32F0 定时器中断 小白掉进的坑(FreeModbus)Timeout
  16. 一个很强的数据字典工具
  17. 毕业设计 stm32地下井盖管道安全监控系统 - 物联网 单片机
  18. Bootstrap4 之栅格系统
  19. 拜伦之女传奇一生:世界第一位计算机程序员
  20. 洛谷 P1638 逛画展

热门文章

  1. 【3D动态思维导图制作软件】万彩脑图大师教程 | 给思维导图设置密码
  2. JAVA版WMS物流仓储管理系统源码,包含PDA端和Web端
  3. 树莓派小车避障之——超声波控制(2.1)
  4. ORACLE 查询删除表的索引和约束 以及 批量删除表的索引和约束
  5. CSS3--用CSS3实现无限循环的无缝滚动
  6. 参数辨识最小二乘法——永磁同步电机矢量控制课题拓展
  7. [Go实战]CGO 入门系列-手把手教程1
  8. TAPA认证咨询,TSR运输公司需要注意大小类别和独立认证机构的检验要求
  9. MySQL使用C语言连接
  10. C语言中几个字符串输出