9

假设我们有两个矩阵AB并且让矩阵CA*B(矩阵乘法不是元素)。我们希望只获得 的对角线条目C,这可以通过 来完成np.diagonal(C)。但是,这会导致不必要的时间开销,因为我们将 A 与 B 相乘,即使我们只需要将其中的每一行A与具有相同“id”的列相乘B,即第 1 行A与第 1行的B列2 of Awith column 2 ofB依此类推:形成对角线的乘法C. 有没有办法使用 Numpy 有效地实现这一目标?我想避免使用循环来控制哪一行与哪一列相乘,相反,我希望有一个内置的 numpy 方法来执行这种操作以优化性能。

提前致谢..

4

2 回答 2

17

我可能会einsum在这里使用:

>>> a = np.random.randint(0, 10, (3,3))
>>> b = np.random.randint(0, 10, (3,3))
>>> a
array([[9, 2, 8],
       [5, 4, 0],
       [8, 0, 6]])
>>> b
array([[5, 5, 0],
       [3, 5, 5],
       [9, 4, 3]])
>>> a.dot(b)
array([[123,  87,  34],
       [ 37,  45,  20],
       [ 94,  64,  18]])
>>> np.diagonal(a.dot(b))
array([123,  45,  18])
>>> np.einsum('ij,ji->i', a,b)
array([123,  45,  18])

对于较大的数组,它比直接进行乘法要快得多:

>>> a = np.random.randint(0, 10, (1000,1000))
>>> b = np.random.randint(0, 10, (1000,1000))
>>> %timeit np.diagonal(a.dot(b))
1 loops, best of 3: 7.04 s per loop
>>> %timeit np.einsum('ij,ji->i', a, b)
100 loops, best of 3: 7.49 ms per loop

[注意:最初我做了元素版本,ii,ii->i而不是矩阵乘法。同样的einsum技巧也有效。]

于 2013-07-03T00:27:16.863 回答
-1
def diag(A,B):
    diags = []
    for x in range(len(A)):
        diags.append(A[x][x] * B[x][x])
    return diags

我相信上面的代码就是你要找的。

于 2013-07-03T00:24:39.433 回答