Python:如何将任意数量的小矩阵动态组合成一个大矩阵

时间:2016-05-01 22:49:23

标签: python numpy matrix

我有这4个矩阵,我希望通过传递n:小矩阵和输出矩阵行和列来动态地将它们组合成一个大矩阵 例如:

[[ 1  2  5  6]
 [ 3  4  7  8]
 [ 9 10 13 14]
 [11 12 15 16]]

输出矩阵:

M = np.bmat( [[x1], [x2], [x3], [x4]] )

我可以使用以下方式手动完成:

invalid 'col.names' specification

4 个答案:

答案 0 :(得分:1)

实施2分钟(版本之前的问题,对某人可能有用):

import numpy as np

a=np.ones((10,10))
b=a*3
c=a*1
d=a*1.5

def combine_matrix(*args):  
    n=len(args)
    rows,cols=args[0].shape
    a=np.zeros((n,rows,cols))
    for i in range(n):
        a[i]=args[i]
    return a

print combine_matrix(a,b,c,d)

如果阵列的大小很大,那么还有改进的地方......

答案 1 :(得分:1)

我认为(但不知道它是否正确),最好是在原地工作并避免每次都使用新方法创建新对象 - 特别是当您多次循环执行时。这些示例仅适用于2d矩阵。但它可以更容易地实现更多维度。最好的是拥有一个大数组,如果它真的很大,那么在numpy.memmap数组中。然后研究它的各个部分。最快的索引(第二个指针)将在cython内存视图上...

?reshape

答案 2 :(得分:1)

[编辑 - 我假设小数组是独立创建的,尽管我的例子是基于拆分(4,2,2)数组。如果它们只是3d阵列的平面,那么'reshape'和'transpose'的某种组合将更好地工作。但即使是这样的解决方案也会生成副本,因为原始值会重新排列。]

让我们列出2x2数组(这里是一个3d数组)。需要挤压,因为这种拆分产生(1,2,2)阵列:

    n = len(A)
    E = np.zeros((n,n))
In [330]: X=np.arange(1,17).reshape(4,2,2)

In [331]: xl=[np.squeeze(i) for i in np.split(X,4,0)]

In [332]: xl
Out[332]: 
[array([[1, 2],
        [3, 4]]), array([[5, 6],
        [7, 8]]), array([[ 9, 10],
        [11, 12]]), array([[13, 14],
        [15, 16]])]

您的bmat方法 - 已更正以生成方形布局

In [333]: np.bmat([[xl[0],xl[1]],[xl[2],xl[3]]])
Out[333]: 
matrix([[ 1,  2,  5,  6],
        [ 3,  4,  7,  8],
        [ 9, 10, 13, 14],
        [11, 12, 15, 16]])

连接方法:

In [334]: np.vstack([np.hstack(xl[:2]),np.hstack(xl[2:])])
Out[334]: 
array([[ 1,  2,  5,  6],
       [ 3,  4,  7,  8],
       [ 9, 10, 13, 14],
       [11, 12, 15, 16]])

由于切片适用于hstack,我也可以在bmat中使用它:

In [335]: np.bmat([xl[:2],xl[2:]])
Out[335]: 
matrix([[ 1,  2,  5,  6],
        [ 3,  4,  7,  8],
        [ 9, 10, 13, 14],
        [11, 12, 15, 16]])

内部bmat(检查其代码)正在使用vstack hstacks的版本(在第一个轴和最后一个轴上连接)。有效地

In [366]: ll=[xl[:2], xl[2:]]

In [367]: np.vstack([np.hstack(row) for row in ll])
Out[367]: 
array([[ 1,  2,  5,  6],
       [ 3,  4,  7,  8],
       [ 9, 10, 13, 14],
       [11, 12, 15, 16]])

您需要指定这些n数组的排列方式。 np.bmat(xl)生成(2,8)矩阵(hstack也是如此)。 np.vstack(xl)生成(8,2)数组。

使用3x3,2x3等子阵列布局来扩展它应该不难。 xl是一个子数组列表。将其修改为所需的子阵列列表并应用bmatstacks的组合。

2x3布局的2个快速版本(4d xl数组比2x3嵌套列表更容易构建,但在功能上将是相同的:

In [369]: xl=np.arange(3*2*2*2).reshape((3,2,2,2))

In [370]: np.vstack([np.hstack(row) for row in xl])
Out[370]: 
array([[ 0,  1,  4,  5],
       [ 2,  3,  6,  7],
       [ 8,  9, 12, 13],
       [10, 11, 14, 15],
       [16, 17, 20, 21],
       [18, 19, 22, 23]])

In [371]: xl=np.arange(2*3*2*2).reshape((2,3,2,2))

In [372]: np.vstack([np.hstack(row) for row in xl])
Out[372]: 
array([[ 0,  1,  4,  5,  8,  9],
       [ 2,  3,  6,  7, 10, 11],
       [12, 13, 16, 17, 20, 21],
       [14, 15, 18, 19, 22, 23]])

答案 3 :(得分:1)

您可以组合转置和重塑操作:

In [1878]: x=arange(24).reshape(4,3,2)

In [1879]: (_,n,m)=x.shape

In [1880]: x.reshape(2,2,n,m).transpose(0,2,1,3).reshape(2*n,2*m)
Out[1880]: 
array([[ 0,  1,  6,  7],
       [ 2,  3,  8,  9],
       [ 4,  5, 10, 11],
       [12, 13, 18, 19],
       [14, 15, 20, 21],
       [16, 17, 22, 23]])