numpy.tensordot#

numpy.tensordot(a, b, axes=2)[source]#

沿指定軸計算張量點積。

給定兩個張量 ab,以及一個包含兩個類陣列物件的類陣列物件 (a_axes, b_axes),將 ab 的元素(分量)的乘積,在由 a_axesb_axes 指定的軸上求和。第三個參數可以是一個單一的非負整數類純量 N;如果是這樣,則 a 的最後 N 個維度和 b 的前 N 個維度會被求和。

參數:
a, barray_like

要進行「點積」運算的張量。

axesint 或 (2,) array_like
  • integer_like 若為整數 N,則依序在 a 的最後 N 個軸和 b 的前 N 個軸上求和。對應軸的大小必須匹配。

  • (2,) array_like 或者,要加總的軸的列表,第一個序列應用於 a,第二個序列應用於 b。兩個元素類陣列物件的長度必須相同。

返回:
outputndarray

輸入的張量點積。

參見

dot, einsum

註解

三個常見的用例是
  • axes = 0 : 張量積 \(a\otimes b\)

  • axes = 1 : 張量點積 \(a\cdot b\)

  • axes = 2 : (預設) 張量雙重縮併 \(a:b\)

axes 是 integer_like 時,用於求值的軸序列將是:從 a 中的倒數第 N 個軸到倒數第 1 個軸,以及從 b 中的第 0 個軸到第 (N-1) 個軸。例如,axes = 2 等於 axes = [[-2, -1], [0, 1]]。當 N-1 小於 0,或當 -N 大於 -1 時,ab 的元素會被定義為 axes

當有多個軸要加總時 - 且它們不是 a (b) 的最後(第一個)軸 - 參數 axes 應包含兩個長度相同的序列,要加總的第一個軸在兩個序列中都先給出,第二個軸次之,依此類推。計算可以參考 numpy.einsum

結果的形狀由第一個張量的非縮併軸,後跟第二個張量的非縮併軸組成。

範例

integer_like 的範例

>>> a_0 = np.array([[1, 2], [3, 4]])
>>> b_0 = np.array([[5, 6], [7, 8]])
>>> c_0 = np.tensordot(a_0, b_0, axes=0)
>>> c_0.shape
(2, 2, 2, 2)
>>> c_0
array([[[[ 5,  6],
         [ 7,  8]],
        [[10, 12],
         [14, 16]]],
       [[[15, 18],
         [21, 24]],
        [[20, 24],
         [28, 32]]]])

array_like 的範例

>>> a = np.arange(60.).reshape(3,4,5)
>>> b = np.arange(24.).reshape(4,3,2)
>>> c = np.tensordot(a,b, axes=([1,0],[0,1]))
>>> c.shape
(5, 2)
>>> c
array([[4400., 4730.],
       [4532., 4874.],
       [4664., 5018.],
       [4796., 5162.],
       [4928., 5306.]])

一種較慢但等效的計算相同結果的方式…

>>> d = np.zeros((5,2))
>>> for i in range(5):
...   for j in range(2):
...     for k in range(3):
...       for n in range(4):
...         d[i,j] += a[k,n,i] * b[n,k,j]
>>> c == d
array([[ True,  True],
       [ True,  True],
       [ True,  True],
       [ True,  True],
       [ True,  True]])

一個利用 + 和 * 多載的擴展範例

>>> a = np.array(range(1, 9))
>>> a.shape = (2, 2, 2)
>>> A = np.array(('a', 'b', 'c', 'd'), dtype=object)
>>> A.shape = (2, 2)
>>> a; A
array([[[1, 2],
        [3, 4]],
       [[5, 6],
        [7, 8]]])
array([['a', 'b'],
       ['c', 'd']], dtype=object)
>>> np.tensordot(a, A) # third argument default is 2 for double-contraction
array(['abbcccdddd', 'aaaaabbbbbbcccccccdddddddd'], dtype=object)
>>> np.tensordot(a, A, 1)
array([[['acc', 'bdd'],
        ['aaacccc', 'bbbdddd']],
       [['aaaaacccccc', 'bbbbbdddddd'],
        ['aaaaaaacccccccc', 'bbbbbbbdddddddd']]], dtype=object)
>>> np.tensordot(a, A, 0) # tensor product (result too long to incl.)
array([[[[['a', 'b'],
          ['c', 'd']],
          ...
>>> np.tensordot(a, A, (0, 1))
array([[['abbbbb', 'cddddd'],
        ['aabbbbbb', 'ccdddddd']],
       [['aaabbbbbbb', 'cccddddddd'],
        ['aaaabbbbbbbb', 'ccccdddddddd']]], dtype=object)
>>> np.tensordot(a, A, (2, 1))
array([[['abb', 'cdd'],
        ['aaabbbb', 'cccdddd']],
       [['aaaaabbbbbb', 'cccccdddddd'],
        ['aaaaaaabbbbbbbb', 'cccccccdddddddd']]], dtype=object)
>>> np.tensordot(a, A, ((0, 1), (0, 1)))
array(['abbbcccccddddddd', 'aabbbbccccccdddddddd'], dtype=object)
>>> np.tensordot(a, A, ((2, 1), (1, 0)))
array(['acccbbdddd', 'aaaaacccccccbbbbbbdddddddd'], dtype=object)