朴素的python方法是:

 sum(grid[x,y] for x in xrange(a) for y in xrange(a-x))


考虑到grid是numpy中的2d方阵,我正在寻找一种提速方法。 tril不起作用,因为它适用于右上角。

最佳答案

您可以先旋转矩阵:

np.sum(np.tril(np.rot90(grid)))


请注意,rot90是视图,而不是数据的副本。以下是一些时序测试,以显示两种版本在两种阵列大小下的相对速度:

In [1]: grid = np.random.rand(10000,10000)

In [2]: a = grid.shape[0]

In [3]: %time sum1 = np.sum(grid[x,y] for x in xrange(a) for y in xrange(a-x))
CPU times: user 18.68 s, sys: 0.04 s, total: 18.72 s
Wall time: 18.60 s

In [4]: %time sum2 = np.sum(np.tril(np.rot90(grid)))
CPU times: user 1.73 s, sys: 0.55 s, total: 2.27 s
Wall time: 2.28 s


第二个版本的速度提高了8倍以上。只是为了确认版本是否等效:

In [5]: np.allclose(sum1, sum2)
Out[5]: True


对于较小的数组:

In [6]: grid = np.random.rand(100,100)

In [7]: a = grid.shape[0]

In [8]: %timeit sum1 = np.sum(grid[x,y] for x in xrange(a) for y in xrange(a-x))
1000 loops, best of 3: 1.9 ms per loop

In [9]: %timeit sum2 = np.sum(np.tril(np.rot90(grid)))
10000 loops, best of 3: 90.4 us per loop


对于这种较小的阵列,第二个版本要快20倍以上。

关于python - 如何使用numpy有效地求和矩阵的左上角?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21731029/

10-09 02:35