2

我有一个 2-d numpy 数组 (MxN) 和另外两个 1-d 数组 (Mx1),它们代表我想要总结的 2-d 数组的每一行的开始和结束索引。我正在寻找在大型数组中执行此操作的最有效方法(最好不必使用循环,这是我目前正在做的)。我想做的一个例子如下。

>>> random.seed(1234)
>>> a = random.rand(4,4)
>>> print a
[[ 0.19151945  0.62210877  0.43772774  0.78535858]
 [ 0.77997581  0.27259261  0.27646426  0.80187218]
 [ 0.95813935  0.87593263  0.35781727  0.50099513]
 [ 0.68346294  0.71270203  0.37025075  0.56119619]]
>>> b = array([1,0,2,1])
>>> c = array([3,2,4,4])
>>> d = empty(4)
>>> for i in xrange(4):
    d[i] = sum(a[i, b[i]:c[i]]) 

>>> print d
[ 1.05983651  1.05256841  0.8588124   1.64414897]

我的问题类似于以下问题,但是,我认为那里提出的解决方案不会非常有效。索引对之间子数组中值的 Numpy 总和在那个问题中,他们想要找到同一行的多个子集的总和,因此cumsum()可以使用。但是,我每行只会找到一个总和,所以我认为这不是计算总和的最有效方法。

编辑:对不起,我在我的代码中犯了一个错误。循环内的行先前已读取d[i] = sum(a[b[i]:c[i]])。我忘记了第一维的索引。每组开始和结束索引对应于二维数组中的一个新行。

4

1 回答 1

2

你可以这样做:

from numpy import array, random, zeros
random.seed(1234)
a = random.rand(4,4)
b = array([1,0,2,1])
c = array([3,2,4,4])

lookup = zeros(len(a) + 1, a.dtype)
lookup[1:] = a.sum(1).cumsum()
d = lookup[c] - lookup[b]
print d

如果您的 b/c 数组很大并且您要求和的窗口很大,这可能会有所帮助。因为您的窗口可能会重叠,例如 2:4 和 1:4 几乎相同,所以您实际上是在重复操作。通过将 cumsum 作为每个处理步骤,您可以减少重复操作的数量,并且可以节省时间。如果您的窗口很小并且 b/c 很小,这将无济于事,主要是因为您将对 a 矩阵中您不太关心的部分求和。希望有帮助。

于 2012-11-20T16:59:11.147 回答