在 numpy 中计算对角线和

Computing diagonal sums in numpy

我有一个相当大的矩形 numpy 数组,形状为 (m, n),例如:

>>> a.shape
(27584, 34092)

我必须计算数组中每个 anti-diagonal 的总和。这个新数组的形状为 (m + n - 1,).

最简单的方法是:

m, n = a.shape
r = np.zeros(m + n - 1)
for i in range(m):
    for j in range(n):
        r[i + j] += a[i][j]

# r is the sum of all anti-diagonals of a

这显然很慢,有什么方法可以使用巧妙的 numpy 原语来执行计算吗?我唯一的其他选择是用 C++ 编写代码,这也是可行的 - 但需要更多工作。

在我看来,最直观的解决方案是:

  • 使用 a[::-1] 来“翻转”行的顺序,这样你就可以 在“正常”对角线上操作,
  • 使用np.diagonal访问每条对角线,
  • 对返回的对角线求和,
  • 将上面的代码放在列表理解中。

所以整个代码可以是:

result = [np.diagonal(a[::-1], offs).sum() for offs in range(-a.shape[0] + 1, a.shape[1])]

它应该 运行 比您的代码快得多。

因为你的源数组很大,也许你会得到一些速度 增益:

  • 计算“翻转”数组一次,在开始时,
  • 然后对这个数组进行操作:

所以修改后的代码,包括关于 np.trace 的提示(见评论), 可以是:

b = a[::-1]
result = [np.trace(b, offs) for offs in range(-a.shape[0] + 1, a.shape[1])]