将数组数组转换为矩阵

时间:2011-12-02 01:09:12

标签: numpy

在我的应用程序中,携带矩阵矩阵很有意义。因为numpy不喜欢它,并且因为使用数组大部分时间都比较轻,所以我最终得到了数组数组。我对他们很满意。

看起来像是:

    [ [S11hh S11hv] [S12hh S12hv] ]
    [ [S11vh S11vv] [S12vh S12vv] ]
S = [                             ]
    [ [S21hh S21hv] [S22hh S22hv] ]
    [ [S21vh S21vv] [S22vh S22vv] ]

(这是针对水平和垂直极化中的反射和透射系数,它是光学系统。)

然而,在我的代码中的某些时候,我需要使用所有S进行矩阵乘法,而不是只使用它的一部分:

M = S.dot(L)

其中L看起来像:

    [ [L1hh L1hv] ]
    [ [L1vh L1vv] ]
L = [             ]
    [ [L2hh L2hv] ]
    [ [L2vh L2vv] ]

如果我天真地跑

M = S.dot(L)

我最终得到了6个维度的东西,这不是我想要的。实际上我希望结果与我的数组数组只是矩阵时会发生的结果完全相似:

    [ S11hh S11hv S12hh S12hv ]
    [ S11vh S11vv S12vh S12vv ]
S = [ S21hh S21hv S22hh S22hv ]
    [ S21vh S21vv S22vh S22vv ]

    [ L1hh L1hv ]
    [ L1vh L1vv ]
L = [ L2hh L2hv ]
    [ L2vh L2vv ]

然后我将4个元素重新分组。

从这些数组中制作矩阵的优雅numpyic方法是什么?我试过bmat,但是bmat对我所拥有的不满意;由于某种原因,它适用于矩阵列表,但不适用于4D阵列。

2 个答案:

答案 0 :(得分:0)

您可以创建一个大矩阵而不是数组数组(您可以使用bmat)。这将使大点产品成为可能。然后,您可以使用切片视图引用每个子矩阵。

答案 1 :(得分:0)

由于存在关于转置的技巧(矩阵或矩阵的转置不是大等效矩阵的转置),并且由于bmat对原始数据结构不满意,我提出了该代码:

def ArrayOfArrayToMatrix(a, transpose=False):
    """
    >>> a1 = np.array([[1, 2], [3, 4]])
    >>> a2 = np.array([[5, 6], [7, 8]])
    >>> a3 = np.array([[9, 10], [11, 12]])
    >>> a4 = np.array([[13, 14], [15, 16]])

    With 4D arrays (matrix of matrices):

    >>> a = np.array([[a1, a2], [a3, a4]])
    >>> print ArrayOfArrayToMatrix(a)
    [[ 1  2  5  6]
     [ 3  4  7  8]
     [ 9 10 13 14]
     [11 12 15 16]]
    >>> a = np.array([[a1, a2]])
    >>> print ArrayOfArrayToMatrix(a)
    [[ 1  2  5  6]
     [ 3  4  7  8]]
    >>> print ArrayOfArrayToMatrix(a, True)
    [[ 1  2]
     [ 3  4]
     [ 5  6]
     [ 7  8]]

    With 3D arrays (vector of matrices): 

    >>> a = np.array([a1, a2])
    >>> print ArrayOfArrayToMatrix(a)
    [[ 1  2  5  6]
     [ 3  4  7  8]]
    >>> print ArrayOfArrayToMatrix(a, True)
    [[ 1  2]
     [ 3  4]
     [ 5  6]
     [ 7  8]]

    """
    # bmat doesn't like arrays so we feed it python lists.
    dim = len(a.shape)
    if dim == 3:
        if transpose:
            lst = [elem.T for elem in a]
        else:
            lst = [elem for elem in a]
    elif dim == 4:
        if transpose:
            lst = [[elem.T for elem in row] for row in a]
        else:
            lst = [[elem for elem in row] for row in a]
    else:
        raise TypeError("Only accepts 3D or 4D arrays.")
    mat = np.bmat(lst)
    if transpose:
        mat = mat.T
    return mat

我是否重新发明轮子?