<p>我发现了一种比einsum方法快3倍的方法,而且我不认为它能更快,所以我用另一种方法回答我自己的问题。在</p>
<p>我所希望的是计算出一个公式,这个公式涉及到,属于的位置是真的。这应该会加快大约3倍,因为归属是真实的大约30%的时间。在</p>
<p>我尝试用第一个公式来计算数组的位置,但这不属于第一个问题np.总和. 解决方案是使用<a href="http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.ufunc.reduceat.html" rel="nofollow">np.add.reduceat</a>。在</p>
<p><strong>reduceat</strong>可以在特定切片的列表中减少ufunc(在本例中为add)。所以我只需要创建一个切片列表,这样我就可以减少由角度[归属]产生的一维数组。在</p>
<p>我将展示我的代码和时间安排,这应该是独立的。在</p>
<p>首先,我用reduceat解决方案定义一个函数:</p>
<pre><code>def vote_op(angle, belong, THRES_THETA, lines_lengths_vstacked, max_line_length):
intermediate = (0.3 * (1-(angle[belong]/THRES_THETA)) + 0.7 * (lines_lengths_vstacked[belong]/max_line_length))
b_ind = np.hstack([0, np.cumsum(np.sum(belong, axis=1))])
votes = np.add.reduceat(intermediate, b_ind[:-1])
return votes
</code></pre>
<p>然后比较了基本方法和einsum方法:</p>
^{pr2}$
<p>时间安排:</p>
<pre><code>[2.866840408487671, 2.6822349628234874, 2.665520338478774]
[2.3444239421490725, 2.352450520946098, 2.4150879511222794]
[0.6846337313820605, 0.660780839464234, 0.6091473217964847]
</code></pre>
<p>因此,<strong>还原</strong>解决方案的速度大约是其他两种方法的3倍,并给出了相同的结果。
请注意,这些结果是针对比之前稍大的示例,其中:
属于,角度和线条长度有形状:(3400170)
以及np.count_非零(属于)/属于。大小->;0.16765051903114186</p>
<p><strong>更新</strong>
因为一个角落的案子np.还原(就像在numpy版本'1.11.0rc1')中它不能正确地处理重复的索引,<a href="https://github.com/numpy/numpy/issues/834" rel="nofollow">see</a>,我不得不添加hack to vote_op()函数来处理beyond中的整行都是False的情况。这会导致重复索引和错误的投票结果。我目前的解决方案是修补错误的值,这是可行的,但这是另一步。请参见新投票操作():</p>
<pre><code>def vote_op(angle, belong, THRES_THETA, lines_lengths_vstacked, max_line_length):
intermediate = (0.3 * (1-(angle[belong]/THRES_THETA)) + 0.7 * (lines_lengths_vstacked[belong]/max_line_length))
b_rows = np.sum(belong, axis=1)
b_ind = np.hstack([0, np.cumsum(b_rows)])[:-1]
intermediate = np.hstack([intermediate, 0])
votes = np.add.reduceat(intermediate, b_ind)
votes[b_rows == 0] = 0
return votes
</code></pre>