代码之家  ›  专栏  ›  技术社区  ›  Steztric

二维矩阵“切片”的元素相乘形成三维矩阵

  •  0
  • Steztric  · 技术社区  · 6 年前

    像这样的矩阵乘法

    在python中使用 numpy很容易实现

    导入numpy as np np.array([[1,2,3]])*np.array([[1],[2],[3]]) 数组([[1,2,3], 〔2, 4, 6〕; 〔3, 6, 9〕) < /代码>

    但在我的情况下,我有两个二维矩阵,我想乘它来形成一个三维矩阵。实际上,二维矩阵的第一个“切片”是一个数组,我想用第二个矩阵的第一个“切片”相乘以形成二维矩阵。对于二维矩阵的所有“切片”,这都是继续的。认为第一个是Dimensions [x,z] 而第二个是Dimensions [y,z] 。我想把它们相乘得到 [x,y,z] 。在 numpy 中,是否有一种优雅的方法可以做到这一点?

    很容易在python中使用 numpy

    import numpy as np
    np.array([[1, 2, 3]]) * np.array([[1], [2], [3]])
    
    array([[1, 2, 3],
           [2, 4, 6],
           [3, 6, 9]])
    

    但在我的情况下,我有两个二维矩阵,我想乘它来形成一个三维矩阵。实际上,二维矩阵的第一个“切片”是一个数组,我想用第二个矩阵的第一个“切片”相乘以形成二维矩阵。对于二维矩阵的所有“切片”,这都是继续的。把第一个看作是维度 [x,z] 第二个是维度 [y,z] . 我想把它们乘起来 [x,y,z] . 有优雅的方法吗 麻木 ?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Nils Werner    6 年前

    因为你已经可以把乘法描述为

    [x, z] * [y, z] -> [x, y, z]
    

    最简单的解决方案很可能是使用einsum:

    import numpy as np
    
    A = np.arange(12).reshape(4, 3)
    # array([[ 0,  1,  2],
    #        [ 3,  4,  5],
    #        [ 6,  7,  8],
    #        [ 9, 10, 11]])
    B = np.arange(9).reshape(3, 3)
    # array([[0, 1, 2],
    #        [3, 4, 5],
    #        [6, 7, 8]])
    
    C = np.einsum('xz,yz->xyz', A, B)
    # array([[[ 0,  1,  4],
    #         [ 0,  4, 10],
    #         [ 0,  7, 16]],
    # 
    #        [[ 0,  4, 10],
    #         [ 9, 16, 25],
    #         [18, 28, 40]],
    # 
    #        [[ 0,  7, 16],
    #         [18, 28, 40],
    #         [36, 49, 64]],
    # 
    #        [[ 0, 10, 22],
    #         [27, 40, 55],
    #         [54, 70, 88]]])
    

    另一种选择是简单地使用广播

    D = A[:, None, :] * B[None, :, :]
    np.allclose(D, C)
    # True
    
        2
  •  0
  •   Steztric    6 年前

    我通过对 this StackOverflow question .

    arr = np.array([[1, 2, 3]])
    arr * arr.T
    
    array([[1, 2, 3],
           [2, 4, 6],
           [3, 6, 9]])
    
    mat = np.repeat(arr, 3, axis=0)
    mat
    
    array([[1, 2, 3],
           [1, 2, 3],
           [1, 2, 3]])
    
    mat[:,:,None] * np.transpose(mat[:,None,:], axes=(1, 0, 2))
    
    array([[[1, 2, 3],
            [2, 4, 6],
            [3, 6, 9]],
    
           [[1, 2, 3],
            [2, 4, 6],
            [3, 6, 9]],
    
           [[1, 2, 3],
            [2, 4, 6],
            [3, 6, 9]]])