I have a 1d numpy array with booleans values (mask
) which I would like to convert into a list of slices where the mask is True, e.g.:
mask = [False, True, True, True, False, False, True, True]
and I would like to obtain
[slice(1, 4, None), slice(6, 8, None)]
The numpy masked array operations (in particular np.ma.clump_masked()
) can do that, but the only way I found to use it would be to do the following:
np.ma.clump_masked(np.ma.masked_array(np.ones_like(mask), mask))
which yields exactly what I'm looking for:
[slice(1, 4, None), slice(6, 8, None)]
i.e., generating an array with the same shape as mask
, applying the mask to it, and then computing mask_clumped()
on that.
However, the np.ma.masked_array(np.ones_like(mask), mask)
-step seems unnecessary to me. Is there any way to obtain the list of slices from a simplified operation which I would imagine to look like the following?
np.ma.clump_masked(mask)
np.ma.masked_array
requires a masked array as input, not an ndarray
. One approach is to do what you're currently doing and create a masked array
import numpy as np
mask = np.asarray([False, True, True, True, False, False, True, True])
masked_array = np.ma.masked_array(data=mask, mask=mask)
np.ma.clump_masked(masked_array)
However, I assume you're generating mask
based on some condition? In which case, you can use np.ma.masked_where
. For example, to get all the slices of each even number from 0 to 9:
import numpy as np
arr = np.arange(10)
masked_arr = np.ma.masked_where(arr % 2 == 0, arr)
np.ma.clump_masked(masked_arr)
which outputs:
[slice(0, 1, None),
slice(2, 3, None),
slice(4, 5, None),
slice(6, 7, None),
slice(8, 9, None)]
There are other functions such as np.ma.masked_inside
which will create a masked array and mask all elements within some interval. Check the 'see also' of the masked_where
docs for a list of the related funcitons.