2D mutable iterator/generator
I have a NxN matrix which I want to split into non-overlap KxK block. For each block, I want to assign new values to the elements.
Since this looks like a good place for a generator, I implemented:
def extracted_patches(im, top_left, patch_size, grid_size):
'''Extract patches in row-major order following a specific configuration
Parameters
----------
im : the input image (2D numpy array)
top_left : (y,x) coordinate of the top left point (e.g. (3,5))
grid_size : (cy, cx) how many patches in the y-direction and in the x-direction
patch_size : (h, w) how many pixels for the size of each patch
Returns
-------
a generator that goes through each patch (a numpy array view) in row-major order
'''
for i in xrange(grid_size[0]):
for j in xrange(grid_size[1]):
yield im[top_left[0] + patch_size[0]*i : top_left[0] + patch_size[0]*(i+1)
,top_left[1] + patch_size[1]*j : top_left[1] + patch_size[1]*(j+1)]
Then when I try to change the value of each patch, th开发者_如何学运维e assignment change the variable value instead of the value the generator gives
output_im = np.zeros((patch_size[0]*grid_size[0], patch_size[1]*grid_size[1]))
output_im_it = extracted_patches(output_im, (0,0), patch_size, grid_size)
for i in xrange(grid_size[0]*grid_size[1]):
output_im_it = np.random.random(patch_size)
Can my generator be mutable?
As with any variables holding a numpy array, to change the value "pointed to" you want to avoid assigning to the variable but assign to a slice of it. Try this:
for submat in output_im_it:
submat[:] = np.random.random(patch_size)
As a response to your edit: it seems you have confused the generator object with the values it yields. You can't assign to slices of the generator object itself. You can assign to slices of the numpy arrays, which you can get with e.g. output_im_it.next()
or with a for loop, as above.
精彩评论