这是一种矢量化方法,它以max
NumPythonic 的方式进行逐块查找计算 -
# Get shape of input array
M,N = inArr.shape
# Reshape 2D input array to break it down a 4D array with rows and columns
# being divided by the number of frames. Then, use `max` along the divided axes.
out = (inArr.reshape(nFrames,M/nFrames,nFrames,N/nFrames)).max(axis=(1,3))
样品运行 -
In [107]: inArr
Out[107]:
array([[ 37, 47, 35, 96, 84, 55, 36, 218],
[ 4, 199, 104, 246, 136, 123, 215, 237],
[ 21, 50, 21, 151, 243, 130, 69, 166],
[242, 233, 161, 57, 20, 122, 189, 120],
[175, 52, 114, 202, 13, 134, 30, 29],
[117, 128, 88, 108, 97, 249, 87, 37],
[246, 237, 230, 166, 157, 215, 254, 219],
[156, 41, 71, 94, 114, 174, 223, 25]], dtype=uint8)
In [108]: nFrames = 4
In [109]: downSampleMax(inArr, nFrames)
Out[109]:
array([[199, 246, 136, 237],
[242, 161, 243, 189],
[175, 202, 249, 87],
[246, 230, 215, 254]], dtype=uint8)
In [110]: M,N = inArr.shape
In [111]: (inArr.reshape(nFrames,M/nFrames,nFrames,N/nFrames)).max(axis=(1,3))
Out[111]:
array([[199, 246, 136, 237],
[242, 161, 243, 189],
[175, 202, 249, 87],
[246, 230, 215, 254]], dtype=uint8)
运行时测试 -
In [112]: inArr = np.random.randint(0,255,(512,512)).astype('uint8')
In [113]: nFrames = 32
In [114]: def vectorized_downSampleMax(inArr, nFrames):
...: M,N = inArr.shape
...: return (inArr.reshape(nFrames,M/nFrames,nFrames,N/nFrames)).max(axis=(1,3))
...:
...:
...: def downSampleMax(inArr, nFrames):
...:
...: newArray = np.zeros([nFrames, nFrames], dtype = np.uint8)
...: filterSize = (int(np.ceil(float(inArr.shape[0]) / nFrames)),
...: int(np.ceil(float(inArr.shape[1]) / nFrames)))
...: rowArr = np.linspace(0, inArr.shape[0] - filterSize[0], nFrames).astype(int)
...: colArr = np.linspace(0, inArr.shape[1] - filterSize[1], nFrames).astype(int)
...:
...: for iRow in range(nFrames):
...: for iCol in range(nFrames):
...: newArray[iRow, iCol] = np.max(inArr[rowArr[iRow]: rowArr[iRow] + filterSize[0], colArr[iCol]: colArr[iCol] + filterSize[1]])
...:
...: return newArray
...:
In [115]: %timeit downSampleMax(inArr, nFrames)
10 loops, best of 3: 20.1 ms per loop
In [116]: %timeit vectorized_downSampleMax(inArr, nFrames)
1000 loops, best of 3: 909 µs per loop