Numpy库中einsum函数用法

本文深入探讨了Numpy库中的einsum函数,它遵循爱因斯坦求和约定,能高效地处理多维张量的收缩操作。从一维张量到二维、三维张量的收缩,再到矩阵的迹、对角元素提取、求和、转置等功能,einsum展现了强大的计算能力。通过实例演示,展示了einsum如何简化和加速各种张量运算,为理解和使用提供了清晰的路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

一、一维张量收缩

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

c = ∑ i a i b i c =\sum_i a_i b_i c=iaibi所以einsum 的写法就是:
c = a i b i c= a_i b_i c=aibi用代码表示为:

>>> 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 = a i j a i j = ∑ i , j a i j a i j c=a_{ij }a_{ij}= \sum_{i,j} a_{ij }a_{ij} c=aijaij=i,jaijaij也即求矩阵内积

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

2.2 收缩到一维张量

c i = ∑ j A i j B i j c_i = \sum_j A_{ij} B_{ij} ci=jAijBij c j = ∑ i A i j B i j c_j = \sum_i A_{ij} B_{ij} cj=iAijBij
其中, c i c_i ci为两矩阵对应位置元素相乘后再把列元素相加; c j c_j cj为两矩阵对应位置元素相乘后把行相加

>>> 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
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值