一个函数,它将两个矩阵作为输入,并返回一个带有A * B的矩阵。在Python中

时间:2013-03-28 18:32:28

标签: python vector matrix multiplication

我想弄清楚如何创建点积矩阵。这是我到目前为止所做的代码:

C = [[4,1,9], [6,2,8], [7,3,5]]
D = [[2,9], [5,2], [1,0]]

def prettyPrint(A):
    for i in range(len(A)):
        line = "{0: >7}".format("|"+str(A[i][0]))
        for j in range(1, len(A[i])):
            line = line + "{0: >7}".format(str(A[i][j]))
        line = line + "|"
        print(line)
#for addition of vectors   
def matrixADD(A,B):
    Z = []
    for i in range(len(A)):
        row = []
        for j in range(len(A[0])):
            row.append(A[i][j]+B[i][j])
        Z.append(row)
    return Z
#for subtraction of vectors
def matrixSUB(A,B):
    Z = []
    for i in range(len(A)):
        row = []
        for j in range(len(A[0])):
            row.append(A[i][j]-B[i][j])
        Z.append(row)
    return Z
#for multiplication of vectors
def row(A,i):
    Z = []
    Z.extend(A[i])
    return Z

def col(B,j):
    Z = []
    for row in B:
        Z.append(row[j])
    return Z

def dotProduct(x,y):
    prod = 0
    prod = sum(p*q for p,q in zip(x,y))
    return prod

def matrixMUL(A,B):
    Z = []
    #Need to do.
    return Z

print("\nC * D:")
prettyPrint(matrixMUL(C,D))

这是我遇到麻烦的matrixMUL(A,B)部分。 该程序应该通过这种计算: 例如:

Z = C * D =
row(C,0) • col(D,0)   row(C,0) • col(D,1)
row(C,1) • col(D,0)   row(C,1) • col(D,1)
row(C,2) • col(D,0)   row(C,2) • col(D,1)
Z =
(4*2 + 1*5 + 9*1)   (4*9 + 1*2 + 9*0)
(6*2 + 2*5 + 8*1)   (6*9 + 2*2 + 8*0)
(7*2 + 3*5 + 5*1)   (7*9 + 3*2 + 5*0)
Z =
22    38
30    58
34    69

然后只有这个打印声明:

C * D:
     |22     38|
     |30     58|
     |34     69| 

我需要使用其他树(或三个?不知道是否存在拼写错误)功能。 过去三天我一直在尝试这个,并且已经查看了我能想到的一切。这是我尝试过的一些失败的代码(我只是评论出错的东西):

def matrixMUL(A,B):
    Z = []
    Z.append(int(dotProduct(row(A,B),col(A,B))))
    #if len(col(B,j)) != len(row(A,i)):
        #print("Cannot multiply the two matrices. Incorrect dimensions.")
    #else:
        #for n in range(row(A,i)):
            #for m in range(col(B,j)):
                #Z.append(dotProduct(x,y))
    return Z
    #mult = sum(p*q for p,q in zip(x,y))
    #Z.append(mult)
    #Z = []
    #for i in range(len(A)):
        #row = []
        #for j in range(len(A[0])):
            #row.append(A[i][j]+B[i][j])
        #Z.append(row)
    #return Z    

我不知道还能尝试什么。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

你可以这样做:

def matrixMUL(A,B):
    Z = [[0] * len(B[0]) for zz in range(len(A))]
    for i in range(0,len(A)):
        a = row(A,i)
        for j in range(0,len(B[0])):
            b = col(B,j)
            Z[i][j] = sum(p*q for p,q in zip(a,b))
    return Z

我在编写这样的代码时遇到的一个难点是首先正确初始化矩阵。

如果我们使用Z = [[0] * len(B[0])] * len(A)之类的代码,那么我们最终会创建一个包含Z 引用的列表len(A)相同的长度len(B[0])零的列表。因此,像z[0][0] = 1这样的代码似乎会“神奇地”同时将Z[1][0]Z[2][0]更改为等于1,因为所有这些代码都指向同一元素同样的清单。

通过如上所示使用列表推导初始化矩阵Z,我们可以确定我们在Z中引用了一组唯一列表。

另一种避免需要初始化所有Z(从而完全避免列表引用问题)的方法是:

def matrixMUL2(A,B):
    Z = []
    for i in range(0,len(A)):
        a = row(A,i)
        r = []
        for j in range(0,len(B[0])):
            b = col(B,j)
            r.append(sum(p*q for p,q in zip(a,b)))
        Z.append(r)
    return Z

这两个函数都没有进行尽可能多的错误检查(例如,检查矩阵是否具有相应的尺寸大小,如乘法所需),因此它们尚未达到良好的生产代码标准。另外,正如评论中所建议的那样,如果numpy可用,我强烈建议您使用numpy而不是为此编写自己的代码。