<p>让我们看看:</p>
<p>你的问题还不太清楚,但我现在假设你想大大提高这种平均数。</p>
<pre><code>import numpy as np
from numpy.lib import stride_tricks as st
def mf(A, k_shape= (3, 3)):
m= A.shape[0]- 2
n= A.shape[1]- 2
strides= A.strides+ A.strides
new_shape= (m, n, k_shape[0], k_shape[1])
A= st.as_strided(A, shape= new_shape, strides= strides)
return np.sum(np.sum(A, -1), -1)/ np.prod(k_shape)
if __name__ == '__main__':
A= np.arange(100).reshape((10, 10))
print mf(A)
</code></pre>
<p>现在,您实际期望的性能改进是什么?</p>
<p><strong>更新:</strong><br/>
首先,有一个警告:处于当前状态的代码不能正确地适应“内核”形状。不过,这并不是我现在最关心的问题(不管怎样,我的想法是已经准备好如何适当地适应了)。</p>
<p>我刚刚直观地选择了一个4da的新形状,对我来说,考虑一个2D‘核’中心以原始2da的每个网格位置为中心是非常有意义的</p>
<p>但4D造型可能并不是最好的。我认为这里真正的问题是求和的表现。我们应该能够找到“最佳顺序”(4da),以便充分利用您的机器缓存体系结构。但是,对于“小”数组(这种数组与机器缓存“协同工作”)和那些“大”数组(至少不是那么直接的方式)来说,顺序可能不一样。</p>
<p><strong>更新2:</strong><br/>
这是<code>mf</code>的一个稍微修改的版本。很明显,最好先重塑为一个3D数组,然后不求和,只做点积(这样做的好处是,内核可以是任意的)。但是它仍然比Pauls更新的功能慢3倍(在我的机器上)。</p>
<pre><code>def mf(A):
k_shape= (3, 3)
k= np.prod(k_shape)
m= A.shape[0]- 2
n= A.shape[1]- 2
strides= A.strides* 2
new_shape= (m, n)+ k_shape
A= st.as_strided(A, shape= new_shape, strides= strides)
w= np.ones(k)/ k
return np.dot(A.reshape((m, n, -1)), w)
</code></pre>