2012-11-20 53 views
1

我有一个二维numpy数组(MxN)和另外两个一维数组(Mx1),它们分别表示二维数组的每一行的开始和结束索引我想总结一下。我正在寻找在大数组中执行此操作的最有效方法(最好不必使用循环,这正是我目前所做的)。我想要做的一个例子是以下内容。二维数组中的索引对之间的Numpy和

>>> 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 sum of values in subarrays between pairs of indices在这个问题中,他们想要找到同一行的多个子集的总和,所以可以使用cumsum()。但是,我只会在每行中找到一笔金额,所以我不认为这是计算总和的最有效方法。

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

+0

每次迭代做一个大幅度的矢量化操作不应该太慢。你有没有分析你的代码,发现循环开销很大? – japreiss

+0

总和通常超过20-30个元素,但对于每个函数调用(1200x1200二维数组),完成1200次。此外,每次仿真都会调用约600次函数,并执行了一些仿真,因此循环变得不可忽略。 – user1554752

回答

1

你可以做这样的事情:

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很小,这将不会有太大的帮助,主要是因为你将总结一个你不太在乎的矩阵的部分。希望有所帮助。

+0

对不起,这解决了代码中出现错误时的问题。我已更正了代码并发布了新输出,这正是我试图实现的目标。 – user1554752