In numpy (1.8), I want to move this computation out of a Python loop into something more numpy-ish for better performance:
(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
is a ~2000x2000 array, and tool
is a 25x25 array. (Background context: base and tool are height maps, and I'm trying to figure out the closest approach for tool moved all over base.)
I'm trying to use a striding trick, starting with this:
base_view = np.lib.stride_tricks.as_strided(base, shape=(2000, 2000, 25, 25),
strides=(base.strides * 2))
This would make base_view[10,20]
be a 25x25 array of values from base at the upper left corner of (10, 20).
However, this is failing with "Array too big". From value testing, it looks like it reports this problem when the potential size of the array (e.g. 2000*2000*25*25*8) exceeds 2^32-ish and it's triggering an overflow check that multiplies out all the dimensions. (I am on a 32-bit Python installation).
I feel like I'm missing something -- why won't it let me create this "stride view" when the stride values clearly work? Is there a way to force this?
And more generally, is there a way to optimize my loop above?
Updated: exact error:
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.