Numpy:从子矩阵中有效地扩展矩阵

时间:2016-10-25 14:49:45

标签: python numpy matrix vectorization

给定维数(4x4)的正方形数组D:

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

你怎么能为每个尺寸为(2x2)的子矩阵d创建另一组矩阵D *,这样

D* = [..., 
         [[ 1,  2,  1,  2],
          [ 3,  4,  3,  4],
          [ 1,  2,  1,  2],
          [ 3,  4,  3,  4]]
     ]

然后我希望用D *,D **构建另一个方阵,这样:

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

我的实际起始矩阵D的维度是184x184,所以我发现for循环太慢而无法实现这一点。对于numpy来说,这计算密集吗?或者有没有办法优雅地实现这一目标?

以下是foor-loop伪代码的示例:

segments = [(0,0), (2,2), (0,2), (2, 0)]
for seg in segments:
    actual_seg = D[seg[0]:seg[0]+2, seg[1]:seg[1]+2]
    D*.append(numpy.kron(numpy.ones((2, 2), dtype=int), actual_seg))

2 个答案:

答案 0 :(得分:2)

鉴于D并希望扩展每个此类(2x2)子矩阵,使用np.tilenp.repeat组合的一种方法是 -

m,n = D.shape
out = np.repeat(np.tile(D.reshape(m//2,2,n//2,2),2),2,axis=0).reshape(2*m,2*n)

示例运行 -

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

In [117]: m,n = D.shape

In [118]: np.repeat(np.tile(D.reshape(m//2,2,n//2,2),2),2,axis=0).reshape(2*m,2*n)
Out[118]: 
array([[ 1,  2,  1,  2,  5,  6,  5,  6],
       [ 3,  4,  3,  4,  7,  8,  7,  8],
       [ 1,  2,  1,  2,  5,  6,  5,  6],
       [ 3,  4,  3,  4,  7,  8,  7,  8],
       [ 9, 10,  9, 10, 13, 14, 13, 14],
       [11, 12, 11, 12, 15, 16, 15, 16],
       [ 9, 10,  9, 10, 13, 14, 13, 14],
       [11, 12, 11, 12, 15, 16, 15, 16]])

答案 1 :(得分:0)

from __future__ import print_function
import numpy as np

def fn(m_):
        rows, cols = m_.shape
        assert rows%2==0 and cols%2==0
        return np.reshape(
            np.transpose(
                np.tile(
                    np.transpose(
                        np.reshape(
                            m_,(rows//2,2, cols//2,2)
                        ),(0,2,1,3)),(2,2)), (0,2,1,3)
            ),
            (rows*2,cols*2)
        )

m = np.array([[ 1,  2,  5,  6],
    [ 3,  4,  7,  8],
    [ 9, 10, 13, 14],
    [11, 12, 15, 16]])

print(fn(m))

输出:

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