在numpy(1.8)中,为了获得更好的性能,我希望将这种计算从Python循环中移到更加numpy的地方:
(width, height) = base.shape
(toolw, toolh) = tool.shape
for i in range(0, width-toolw):
for j in range(0, height-toolh):
zdiff[i,j] = (tool - base[i:i+toolw, j:j+toolh]).min()
base
是一个~2000x2000数组,tool
是一个25x25数组。(背景背景:基地和工具是高度地图,我正在试图找出最接近的方法,工具在基地移动。)
我试着用跨步技巧,从这个开始:
^{pr2}$这将使base_view[10,20]
成为(10,20)左上角底数为25x25的值数组。在
然而,这是失败的“数组太大”。从值测试来看,当数组的潜在大小(例如2000*2000*25*25*8)超过2^32 ish时,它会报告此问题,并触发溢出检查,从而将所有维度相乘。(我正在安装32位Python)。在
我觉得我遗漏了一些东西——当步幅值明显有效时,为什么不让我创建这个“步幅视图”?有没有办法强迫你这么做?在
更一般地说,有没有办法优化我上面的循环?在
更新:准确错误:
ValueError Traceback (most recent call last)
<ipython-input-14-313b3d6c74fa> in <module>()
----> 1 newa = np.lib.stride_tricks.as_strided(base, shape=(1000, 1000, 25, 25), strides=(base.strides * 2))
C:\Python27\lib\site-packages\numpy\lib\stride_tricks.pyc in as_strided(x, shape, strides)
28 if strides is not None:
29 interface['strides'] = tuple(strides)
---> 30 array = np.asarray(DummyArray(interface, base=x))
31 # Make sure dtype is correct in case of custom dtype
32 array.dtype = x.dtype
C:\Python27\lib\site-packages\numpy\core\numeric.pyc in asarray(a, dtype, order)
458
459 """
--> 460 return array(a, dtype, copy=False, order=order)
461
462 def asanyarray(a, dtype=None, order=None):
ValueError: array is too big.
我真的不能帮助您使用Strates方法,但是有一个方法应该比您的原始代码更快。它在
tool
数组上循环,而不是在base
数组上循环,这意味着,尽管没有完全矢量化,仍有很多工作要做。在请注意,在您的原始代码中,我更改了范围并切换了宽度和高度,因为我假设这正是您想要的。。在
当然,您需要计算实际函数中的高度和宽度,但为了测试,将它们作为全局变量更容易。
对于给定的数组大小,原始代码在7.38秒内运行,而新代码在我的系统上只需要206毫秒。我假设新代码对于数组大小也更快,但我不确定它的扩展程度
:)
其他可能对您感兴趣或不感兴趣的替代品是使用Numba或Cython,在许多情况下,这应该比您想到的任何“矢量化”numpy代码都要快。。在
相关问题 更多 >
编程相关推荐