【问题标题】:Join matrices in Python without numpy在没有 numpy 的 Python 中加入矩阵
【发布时间】:2014-10-26 19:27:29
【问题描述】:

我使用嵌套数组作为矩阵表示。我创建了以下函数,用于将大小为 2^k 的二次矩阵拆分为四个相等的部分(用于 Strassen 算法):

import itertools
def splitmat(mat):
    n = len(mat)
    return map( \
        lambda (x,y):map(lambda z:z[y[0]:y[1]],mat[x[0]:x[1]]), \
        itertools.product([(0,n/2),(n/2,n)],repeat=2)
    )

现在我试图找到一个反函数,将四个部分连接回一个完整的矩阵。我可以使用两个嵌套循环,但是否有任何 pythonic 方法来实现这一点?我宁愿不使用 numpy 而只使用内置模块。您有任何想法或提示如何实现这一目标吗?

【问题讨论】:

    标签: python arrays python-2.7 matrix


    【解决方案1】:

    你的逆运算可以分成两个更简单的运算:

    1. 连接行(numpy.vstack)
    2. 连接列(numpy.hstack)

    所以,如果您将矩阵分为 4 个子矩阵:

    M = |m1|m2| 
        |m3|m4|
    

    然后M = hstack(vstack(m1, m2), vstack(m3, m4)

    这个操作可以是这样的代码:

    import itertools
    import math
    
    # iterators
    def ihstack(*matrixes):
        return map(lambda rows: itertools.chain(*rows), zip(*matrixes))
    
    def ivstack(*matrixes):
        return itertools.chain(*matrixes)
    
    # main function
    def squarejoin(*matrixes):
        size = int(math.sqrt(len(matrixes)))
        assert size ** 2 == len(matrixes), 'Incorrect number of matrices'
        return _matrixjoin(matrixes, size, size)
    
    def _matrixjoin(matrixes, hsize, vsize):
        print(matrixes, hsize, vsize)
        return ivstack(*(ihstack(*itertools.islice(matrixes, i*hsize, (i+1)*hsize)) for i in range(vsize)))
    

    【讨论】:

      【解决方案2】:

      这里我有一个示例程序,其中 2 循环实现工作并且其意图非常清晰,1 循环实现工作并且恕我直言,稍微不太清楚,最终是 0(显式,顺便说一句)循环实现,唉, 有问题。

      我的投票投给了这两个循环......此外,我想知道我的 0 循环尝试有什么问题

      代码

      import itertools
      
      def pm(m):
          for row in m: print row
      
      mat = []
      n = 8
      for i in range(n):
          mat.append(range(i*n, i*n+n))
      
      # this is shorthand for your splitmat function
      res = map(lambda (x,y):
                map(lambda z:z[y[0]:y[1]],mat[x[0]:x[1]]),
                itertools.product([(0,n/2),(n/2,n)],repeat=2))
      pm(res)
      
      print "\n2 cycles"
      mat = []
      for i, j in ((0,1),(2,3)):
          for a, b in zip(res[i],res[j]):
              mat.append(a+b)
      pm(mat)
      
      print "\n1 cycle"
      mat = []
      for i, j in ((0,1),(2,3)):
          map(lambda x: mat.append(x[0]+x[1]), zip(res[i],res[j]))
      pm(mat)
      
      print "\n0 cycles"
      mat =  map(lambda i_j: 
             map(lambda x: x[0]+x[1], zip(res[i_j[0]],res[i_j[1]])), ((0,1),(2,3)))
      pm(mat)
      

      输出

      [[0, 1, 2, 3], [8, 9, 10, 11], [16, 17, 18, 19], [24, 25, 26, 27]]
      [[4, 5, 6, 7], [12, 13, 14, 15], [20, 21, 22, 23], [28, 29, 30, 31]]
      [[32, 33, 34, 35], [40, 41, 42, 43], [48, 49, 50, 51], [56, 57, 58, 59]]
      [[36, 37, 38, 39], [44, 45, 46, 47], [52, 53, 54, 55], [60, 61, 62, 63]]
      
      2 cicli
      [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]
      
      1 ciclo
      [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]
      
      0 cicli
      [[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]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-13
        • 1970-01-01
        • 2012-08-28
        • 2020-08-27
        相关资源
        最近更新 更多