【问题标题】:Inverse cumsum for numpynumpy的逆cumsum
【发布时间】:2015-07-29 18:15:02
【问题描述】:

A 是一个 ((d,e)) numpy 数组。我计算一个 ((d,e)) numpy 数组 B,在其中我计算条目 B[i,j] 如下

b=0
for k in range(i+1,d):
    for l in range(j+1,e):
        b=b+A[k,l]
B[i,j]=b

也就是说,B[i,j]是A[k,l]取所有索引k>i,l>j的总和;这与应用于两个轴的通常 cumsum 有点相反。我想知道是否有更优雅和更快的方法来做到这一点(例如使用 np.cumsum)?

【问题讨论】:

  • 你能举一个实际数据和预期结果的小例子吗?!您还可以添加“python”标签。
  • np.cumsum(np.cumsum(A[::-1, :], axis=0)[::-1, ::-1], axis=1)[:, ::-1] 之类的东西可能会让你走完大约 99% 的路……

标签: python numpy matrix cumsum


【解决方案1】:

假设您正在尝试这样做:

A = np.arange(15).reshape((5, -1))

def cumsum2_reverse(arr):
    out = np.empty_like(arr)
    d, e = arr.shape
    for i in xrange(d):
        for j in xrange(e):
            b = 0
            for k in xrange(i + 1, d):
                for l in xrange(j + 1, e):
                    b += arr[k, l]
            out[i, j] = b
    return out

如果你这样做了,

In [1]: A_revsum = cumsum2_reverse(A)

In [2]: A_revsum
Out[2]: 
array([[72, 38,  0],
      [63, 33,  0],
      [48, 25,  0],
      [27, 14,  0],
      [ 0,  0,  0]])

您可以在倒序数组上使用np.cumsum 来计算总和。例如,起初您可能会尝试类似于@Jaime 建议的方法:

In [3]: np.cumsum(np.cumsum(A[::-1, ::-1], 0), 1)[::-1, ::-1]
Out[3]:
array([[105,  75,  40],
       [102,  72,  38],
       [ 90,  63,  33],
       [ 69,  48,  25],
       [ 39,  27,  14]])

这里我们记得np.cumsum 以第一列(在本例中为最后一列)中的值开头,因此为了确保那里为零,您可以移动此操作的输出。这可能看起来像:

def cumsum2_reverse_alt(arr):
    out = np.zeros_like(arr)
    out[:-1, :-1] = np.cumsum(np.cumsum(arr[:0:-1, :0:-1], 0), 1)[::-1, ::-1]
    return out

这给出了与上面相同的值。

In [4]: (cumsum2_reverse(A) == cumsum2_reverse_alt(A)).all()
Out[4]: True

请注意,使用np.cumsum 的方法对于大型数组来说要快得多。例如:

In [5]: A=np.arange(3000).reshape((50, -1))

In [6]: %timeit cumsum2_reverse(A)
1 loops, best of 3: 453 ms per loop

In [7]: %timeit cumsum2_reverse_alt(A)
10000 loops, best of 3: 24.7 us per loop

【讨论】:

  • 谢谢,这行得通!我认为另一种方法是采用 np.rot90(A,2) 然后对两个轴应用 cumsum,尽管我还没有将它与您的解决方案进行基准测试。
猜你喜欢
  • 2012-10-14
  • 2020-02-04
  • 2013-05-19
  • 2011-01-16
  • 2018-08-16
  • 2019-01-09
  • 1970-01-01
  • 2021-12-27
相关资源
最近更新 更多