I would like to create a 3d mask array based on a 2d array of 'depths' that indicate the extent to which the third dimension is filled with ones. I had hoped there would've been a vectorized solution to this within numpy rather than resorting to for loops. For example:
tst = np.arange(1, 10).reshape(3,3) # depths referred to above
blk = np.zeros(shape=(3,3,9)) # the output 3d array to be filled with ones or zeros
The intended results at the following example positions would be:
blk[0,0]
array([1., 0., 0., 0., 0., 0., 0., 0., 0.])
blk[1,2]
array([1., 1., 1., 1., 1., 1., 0., 0., 0.])
blk[2,2]
array([1., 1., 1., 1., 1., 1., 1., 1., 1.])
Does anyone have any ideas/hints on this?
You can use broadcasting, comparing to numpy.arange
:
blk = (tst[..., None] > np.arange(tst.max())[None, None]).astype(int)
Output:
array([[[1, 0, 0, 0, 0, 0, 0, 0, 0], # blk[0, 0]
[1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0]],
[[1, 1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 0, 0, 0]], # blk[1, 2]
[[1, 1, 1, 1, 1, 1, 1, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1]]]) # blk[2, 2]