以正确的顺序从数组构建块矩阵

时间:2014-06-05 02:35:30

标签: python arrays numpy matrix

我有一个与此类似的numpy数组:

a = np.arange(0,100).reshape(25,4)
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, 27],
       [28, 29, 30, 31],
       [32, 33, 34, 35],
       [36, 37, 38, 39],
       [40, 41, 42, 43],
       [44, 45, 46, 47],
       [48, 49, 50, 51],
       [52, 53, 54, 55],
       [56, 57, 58, 59],
       [60, 61, 62, 63],
       [64, 65, 66, 67],
       [68, 69, 70, 71],
       [72, 73, 74, 75],
       [76, 77, 78, 79],
       [80, 81, 82, 83],
       [84, 85, 86, 87],
       [88, 89, 90, 91],
       [92, 93, 94, 95],
       [96, 97, 98, 99]])

我想使用这个数组以非常精确的顺序创建一个块矩阵。每个块必须是一个方阵,由a的相应列构成。因此,在这种情况下,我们有4个5X5块。一种方法是:

a = np.arange(0,100).reshape(25,4)
A = a[:, 0].reshape(np.sqrt(a.shape[0]), np.sqrt(a.shape[0]))
B = a[:, 1].reshape(np.sqrt(a.shape[0]), np.sqrt(a.shape[0]))
C = a[:, 2].reshape(np.sqrt(a.shape[0]), np.sqrt(a.shape[0]))
D = a[:, 3].reshape(np.sqrt(a.shape[0]), np.sqrt(a.shape[0]))

np.bmat([[A,B],[C,D]])

matrix([[ 0,  4,  8, 12, 16,| 1,  5,  9,  13, 17],
        [20, 24, 28, 32, 36,| 21, 25, 29, 33, 37],
        [40, 44, 48, 52, 56,| 41, 45, 49, 53, 57],
        [60, 64, 68, 72, 76,| 61, 65, 69, 73, 77],
        [80, 84, 88, 92, 96,| 81, 85, 89, 93, 97],
         --------------------------------------- ,
        [ 2,  6, 10, 14, 18,| 3,  7,  11, 15, 19],
        [22, 26, 30, 34, 38,| 23, 27, 31, 35, 39],
        [42, 46, 50, 54, 58,| 43, 47, 51, 55, 59],
        [62, 66, 70, 74, 78,| 63, 67, 71, 75, 79],
        [82, 86, 90, 94, 98,| 83, 87, 91, 95, 99]])

但是,我需要构建此矩阵而不“手动”创建每个矩阵,并能够将此方法推广到更多维度(3X3,4X4等)

谢谢!

1 个答案:

答案 0 :(得分:2)

作为(长)单线:

In [14]: a = np.arange(0,100).reshape(25,4)

In [15]: a.T.reshape(2, 2, 5, 5).transpose(0, 2, 1, 3).reshape(10, 10)
Out[15]:
array([[ 0,  4,  8, 12, 16,  1,  5,  9, 13, 17],
       [20, 24, 28, 32, 36, 21, 25, 29, 33, 37],
       [40, 44, 48, 52, 56, 41, 45, 49, 53, 57],
       [60, 64, 68, 72, 76, 61, 65, 69, 73, 77],
       [80, 84, 88, 92, 96, 81, 85, 89, 93, 97],
       [ 2,  6, 10, 14, 18,  3,  7, 11, 15, 19],
       [22, 26, 30, 34, 38, 23, 27, 31, 35, 39],
       [42, 46, 50, 54, 58, 43, 47, 51, 55, 59],
       [62, 66, 70, 74, 78, 63, 67, 71, 75, 79],
       [82, 86, 90, 94, 98, 83, 87, 91, 95, 99]])

如果它是相关的,请注意最后一个重塑会触发一个副本,所以你得到的是一个新数组,而不是旧数组的视图。

对于一般情况,如果您有m x n形状p x q,您可以这样做:

In [24]: m = 4; n = 2; p = 3; q = 5

In [25]: a = np.arange(m*n*p*q).reshape(p*q, m*n)

In [26]: a.T.reshape(m, n, p, q).transpose(0, 2, 1, 3).reshape(m*p, n*q)
Out[26]:
array([[  0,   8,  16,  24,  32,   1,   9,  17,  25,  33],
       [ 40,  48,  56,  64,  72,  41,  49,  57,  65,  73],
       [ 80,  88,  96, 104, 112,  81,  89,  97, 105, 113],
       [  2,  10,  18,  26,  34,   3,  11,  19,  27,  35],
       [ 42,  50,  58,  66,  74,  43,  51,  59,  67,  75],
       [ 82,  90,  98, 106, 114,  83,  91,  99, 107, 115],
       [  4,  12,  20,  28,  36,   5,  13,  21,  29,  37],
       [ 44,  52,  60,  68,  76,  45,  53,  61,  69,  77],
       [ 84,  92, 100, 108, 116,  85,  93, 101, 109, 117],
       [  6,  14,  22,  30,  38,   7,  15,  23,  31,  39],
       [ 46,  54,  62,  70,  78,  47,  55,  63,  71,  79],
       [ 86,  94, 102, 110, 118,  87,  95, 103, 111, 119]])