【问题标题】:Numpy: efficiently expand a matrix from submatrixNumpy:从子矩阵有效地扩展矩阵
【发布时间】:2016-10-25 14:49:45
【问题描述】:

给定一个维度为 (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 来说计算量太大了吗?或者有没有办法优雅而高效地实现这一目标?

这里是一个for循环伪代码的例子:

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))

【问题讨论】:

  • 这个简单的例子不足以理解将 D 带到 D* 和 D** 的数学函数。你能更好地形式化你如何创建 D* 和 D** 吗?也许包括你的 4-for 循环代码
  • 因此,D* 表示“将每个 非重叠 子矩阵 2 2 平铺并制作一个列表”,而 D** 表示“将所有这些矩阵平铺在 D* 中成一个大矩阵”?这是你想要的吗?

标签: python numpy matrix vectorization


【解决方案1】:

鉴于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]])

【讨论】:

    【解决方案2】:
    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]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-19
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 2015-03-16
      • 1970-01-01
      • 2017-02-19
      • 2018-09-05
      相关资源
      最近更新 更多