在 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])]
我有一个相当大的矩形 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])]