【问题标题】:Matrix multiply a numpy array of matrices矩阵乘以一个numpy矩阵数组
【发布时间】:2015-03-06 04:42:30
【问题描述】:

我正在扩展旨在对 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.]]])

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    我在这篇文章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]]]
    

    【讨论】:

    • 您的主要兴趣是构建索引字符串,还是想更深入地了解einsum 的运作方式?源代码是C。
    • 我想了解如何构造索引字符串(刚刚在帖子中澄清了这一点)。
    • 这些测试示例可能会有所帮助:github.com/numpy/numpy/blob/master/numpy/core/tests/…
    【解决方案2】:

    您也可以使用 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
    

    【讨论】:

    • 我刚开始使用 pandas,所以很高兴看到我将如何使用它。 pandas 中的示例使用了循环,因此最好将其与numpy.dot 循环进行比较。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多