Add two matrices in python

前端 未结 4 1359
独厮守ぢ
独厮守ぢ 2020-12-17 15:45

I\'m trying to write a function that adds two matrices to pass the following doctests:

  >>> a = [[1, 2], [3, 4]]
  >>> b = [[2, 2], [2, 2]         


        
相关标签:
4条回答
  • 2020-12-17 16:12

    Matrix library

    You can use the numpy module, which has support for this.

    >>> import numpy as np
    
    >>> a = np.matrix([[1, 2], [3, 4]])
    >>> b = np.matrix([[2, 2], [2, 2]])
    
    >>> a+b
    matrix([[3, 4],
            [5, 6]])
    

    Home-grown solution: heavyweight

    Assuming you wanted to implement it yourself, you'd set up the following machinery, which would let you define arbitrary pairwise operations:

    from pprint import pformat as pf
    
    class Matrix(object):
        def __init__(self, arrayOfRows=None, rows=None, cols=None):
            if arrayOfRows:
                self.data = arrayOfRows
            else:
                self.data = [[0 for c in range(cols)] for r in range(rows)]
            self.rows = len(self.data)
            self.cols = len(self.data[0])
    
        @property
        def shape(self):          # myMatrix.shape -> (4,3)
            return (self.rows, self.cols)
        def __getitem__(self, i): # lets you do myMatrix[row][col
            return self.data[i]
        def __str__(self):        # pretty string formatting
            return pf(self.data)
    
        @classmethod
        def map(cls, func, *matrices):
            assert len(set(m.shape for m in matrices))==1, 'Not all matrices same shape'
    
            rows,cols = matrices[0].shape
            new = Matrix(rows=rows, cols=cols)
            for r in range(rows):
                for c in range(cols):
                    new[r][c] = func(*[m[r][c] for m in matrices], r=r, c=c)
            return new
    

    Now adding pairwise methods is as easy as pie:

        def __add__(self, other):
            return Matrix.map(lambda a,b,**kw:a+b, self, other)
        def __sub__(self, other):
            return Matrix.map(lambda a,b,**kw:a-b, self, other)
    

    Example:

    >>> a = Matrix([[1, 2], [3, 4]])
    >>> b = Matrix([[2, 2], [2, 2]])
    >>> b = Matrix([[0, 0], [0, 0]])
    
    >>> print(a+b)
    [[3, 4], [5, 6]]                                                                                                                                                                                                      
    
    >>> print(a-b)
    [[-1, 0], [1, 2]]
    

    You can even add pairwise exponentiation, negation, binary operations, etc. I do not demonstrate it here, because it's probably best to leave * and ** for matrix multiplication and matrix exponentiation.


    Home-grown solution: lightweight

    If you just want a really simple way to map an operation over only two nested-list matrices, you can do this:

    def listmatrixMap(f, *matrices):
        return \
            [
                [
                    f(*values) 
                    for c,values in enumerate(zip(*rows))
                ] 
                for r,rows in enumerate(zip(*matrices))
            ]
    

    Demo:

    >>> listmatrixMap(operator.add, a, b, c))
    [[3, 4], [5, 6]]
    

    With an additional if-else and keyword argument, you can use indices in your lambda. Below is an example of how to write a matrix row-order enumerate function. The if-else and keyword were omitted above for clarity.

    >>> listmatrixMap(lambda val,r,c:((r,c),val), a, indices=True)
    [[((0, 0), 1), ((0, 1), 2)], [((1, 0), 3), ((1, 1), 4)]]
    

    edit

    So we could write the above add_matrices function like so:

    def add_matrices(a,b):
        return listmatrixMap(add, a, b)
    

    Demo:

    >>> add_matrices(c, d)
    [[11, 4], [12, 6], [15, 19]]
    
    0 讨论(0)
  • 2020-12-17 16:21

    One more solution:

    map(lambda i: map(lambda x,y: x + y, matr_a[i], matr_b[i]), xrange(len(matr_a)))
    
    0 讨论(0)
  • 2020-12-17 16:23
    def addM(a, b):
        res = []
        for i in range(len(a)):
            row = []
            for j in range(len(a[0])):
                row.append(a[i][j]+b[i][j])
            res.append(row)
        return res
    
    0 讨论(0)
  • 2020-12-17 16:23
    from itertools import izip
    
    def add_matrices(c, d):
        return [[a+b for a, b in izip(row1, row2)] for row1, row2 in izip(c, d)]
    

    But as said above, there is no need to reinvent the wheel, just use numpy, which is likely to be faster and more flexible.

    0 讨论(0)
提交回复
热议问题