You can do this:
print arr.reshape(2,2,2,2).swapaxes(1,2).reshape(2,2,4).max(axis=-1)
[[ 0.439 0.962]
[-0.038 0.476]]
To explain starting with:
arr=np.array([[0.393,-0.428,-0.546,0.103],
[0.439,-0.154,0.962,0.37,],
[-0.038,-0.216,-0.314,0.458],
[-0.123,-0.881,-0.204,0.476]])
We first want to group the axes into relevant sections.
tmp = arr.reshape(2,2,2,2).swapaxes(1,2)
print tmp
[[[[ 0.393 -0.428]
[ 0.439 -0.154]]
[[-0.546 0.103]
[ 0.962 0.37 ]]]
[[[-0.038 -0.216]
[-0.123 -0.881]]
[[-0.314 0.458]
[-0.204 0.476]]]]
Reshape once more to obtain the groups of data we want:
tmp = tmp.reshape(2,2,4)
print tmp
[[[ 0.393 -0.428 0.439 -0.154]
[-0.546 0.103 0.962 0.37 ]]
[[-0.038 -0.216 -0.123 -0.881]
[-0.314 0.458 -0.204 0.476]]]
Finally take the max along the last axis.
This can be generalized, for square matrices, to:
k = arr.shape[0]/2
arr.reshape(k,2,k,2).swapaxes(1,2).reshape(k,k,4).max(axis=-1)
Following the comments of Jamie and Dougal we can generalize this further:
n = 2 #Height of window
m = 2 #Width of window
k = arr.shape[0] / n #Must divide evenly
l = arr.shape[1] / m #Must divide evenly
arr.reshape(k,n,l,m).max(axis=(-1,-3)) #Numpy >= 1.7.1
arr.reshape(k,n,l,m).max(axis=-3).max(axis=-1) #Numpy < 1.7.1