矩阵相乘一个numpy矩阵数组

xwmevbvl  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(140)

我正在扩展设计用于在2个向量上执行函数的代码,以便它可以处理2个向量数组。我使用numpy.dot来计算两个3x3矩阵的乘积。现在我想用一个3x3矩阵的数组来做这个。我不知道如何使用numpy.einsum来实现这一点,但我认为这正是我所需要的,我只是在努力理解它是如何工作的。
这里有一个例子,我想使用一个循环。有没有一种方法可以做到这一点没有循环?

>>> import numpy as np
>>> m = np.arange(27).reshape(3,3,3)
>>> print m
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]]])
>>> m2 = np.zeros(m.shape)
>>> for i in length(m):
        m2[i] = np.dot(m[i],m[i])
>>> print m2
    array([[[   15.,    18.,    21.],
            [   42.,    54.,    66.],
            [   69.,    90.,   111.]],

           [[  366.,   396.,   426.],
            [  474.,   513.,   552.],
            [  582.,   630.,   678.]],

           [[ 1203.,  1260.,  1317.],
            [ 1392.,  1458.,  1524.],
            [ 1581.,  1656.,  1731.]]])
4zcjmb1e

4zcjmb1e1#

我在这篇文章Python, numpy, einsum multiply a stack of matrices中发现了一个numpy.einsum语法,它可以实现我想要的功能。我不清楚为什么它会起作用,我想知道如何构造索引字符串以备将来使用。

>>> print np.einsum('fij,fjk->fik', V, V)
    [[[  15   18   21]
      [  42   54   66]
      [  69   90  111]]

     [[ 366  396  426]
      [ 474  513  552]
      [ 582  630  678]]

     [[1203 1260 1317]
      [1392 1458 1524]
      [1581 1656 1731]]]
fjaof16o

fjaof16o2#

你也可以使用Pandas。在下面的示例中,'p'相当于'm',是数据的3D表示。使用列表解析,p2计算每个矩阵的点积。出于比较的目的,然后将结果转换回numpy数组列表。

import pandas as pd

%%timeit
m = np.arange(27).reshape(3,3,3)
p = pd.Panel(m)
p2 = [p[i].dot(p[i]) for i in p.items]

1000 loops, best of 3: 846 µs per loop

m2 = [p2[i].values for i in p2.items]
print(m2)

[array([[ 15,  18,  21],
       [ 42,  54,  66],
       [ 69,  90, 111]]), 
array([[366, 396, 426],
       [474, 513, 552],
       [582, 630, 678]]), 
array([[1203, 1260, 1317],
       [1392, 1458, 1524],
       [1581, 1656, 1731]])]

然而,Numpy要快得多。

%%timeit
np.einsum('fij,fjk->fik', m, m)

100000 loops, best of 3: 5.01 µs per loop

直接与np.dot比较:

%%timeit
[np.dot(m[i], m[i]) for i in range(len(m))]

100000 loops, best of 3: 6.78 µs per loop
jtoj6r0c

jtoj6r0c3#

我知道这是一个老职位,但如果有人在2023年(或更晚)结束了这里. matmul做你想要的:

>>> import numpy as np
>>> m = np.arange(27).reshape(3,3,3)
>>> print(np.matmul(m, m))
[[[  15   18   21]
  [  42   54   66]
  [  69   90  111]]

 [[ 366  396  426]
  [ 474  513  552]
  [ 582  630  678]]

 [[1203 1260 1317]
  [1392 1458 1524]
  [1581 1656 1731]]]

如果传递给matmul的两个操作数是N维数组(N>2),则它们被视为存储在最后两个维度中的矩阵的堆栈。例如np.matmul(a, b),其中a是4×6×5×2,b是4×6×2×3(即ab分别是5×2和2×3矩阵的4×6堆栈)给出了存储在4×6×5×3 ndarray中的5×3矩阵的4×6堆栈。

相关问题