Reputation: 9844
I have to "divide" an n x m
array in regions using a mask input.
For example, suppose I have a 20 x 20
array. My mask is the following (5 x 5
) -- always:
where the numbers represent the regions in which the cells take part. This mask is not an input, that is just an ndarray
. This mask just represent how I should slice my 20 x 20
at every 5 x 5
neighborhood.
For example, the first region comprehend the indices:
(0,0), (1,0), (1,1), (2,0), (2,1), (2,2)
For each 5 x 5
neighborhood of my 20 x 20
array, I should return the values that are in each of the 8
regions.
I know how to do that with a "standard code", but I wondering if there is a Pythonic way of do that, possible with a concise code.
As a code example, I could do something like:
def slice_in_regions(data, x_dim, y_dim):
for x in xrange(0, x_dim, 5):
for y in xrange(0, y_dim, 5):
neighbors = data[x:x+4, y:y+4]
region1 = [neighbors[0,0], neighbors[1,0], neighbors[1,1], neighbors[2,0], neighbors[2,1], neighbors[2,2]]
# region2, region3...
However, that doesn't seem to be a good way to do that. Moreover, I'm counting on that my data will dimension be multiple of 5
.
Thank you.
Upvotes: 0
Views: 660
Reputation: 12773
It seems you could probably just resize your mask, e.g. if you're already using numpy
,
mask = mask.repeat(4, axis=0).repeat(4, axis=1)
# Then you apply the mask using
values = data[mask]
Otherwise,
import numpy as np
mask = np.repeat(mask, 4, axis=0).repeat(4, axis=1)
# Then you apply the mask using
values = np.array(data)[mask]
Individual regions
If you need to access each region individually, you could precede the previous by using a labelled mask; as the labels will be grown into labelled regions you can then use, e.g.
values = [ data[mask==l] for l in range(1, mask.max()+1)]
Here values will be a list of arrays where each item corresponds to a labelled region in mask
.
Generating the labelled mask
For completeness, to get from a binary mask to a labelled mask where every on pixel has it's own label you could use scipy.ndimage.label
mask = ndimage.label(mask, [[0,0,0],[0,1,0],[0,0,0]])
or if using a region labelling function is overkill, you can achieve a similar result using
mask[mask] = range(1,mask.sum()+1)
Upvotes: 1