Rowandish
Rowandish

Reputation: 2735

How to efficiently use a index array as a mask to turn a numpy array into a boolean array?

I have a numpy array like this:

>>> I
array([[ 1.,  0.,  2.,  1.,  0.],
       [ 0.,  2.,  1.,  0.,  2.]])

And an array A like this:

>>> A = np.ones((2,5,3))

I'd like to obtain the following matrix:

>>> result
array([[[ False,  False,  True],
        [ False,  True,  True],
        [ False,  False,  False],
        [ False,  False,  True],
        [ False,  True,  True]],

       [[ False,  True,  True],
        [ False,  False,  False],
        [ False,  False,  True],
        [ False,  True,  True],
        [ False,  False,  False]]], dtype=bool)

It is better to explain with an example:
I[0,0] = 1 -> result[0,0,:2] = False and result[1,1,2:] = True
I[1,0] = 0 -> result[1,1,0] = False and result[1,1,1:] = True

Here is my current implementation (correct):

result = np.empty((A.shape[0], A.shape[1], A.shape[2]))
r = np.arange(A.shape[2])
for i in xrange(A.shape[0]):
    result[i] = r > np.vstack(I[i])

print result.astype(np.bool)

Is there a way to implement in a faster way (avoiding the for loop)?

Thanks!

Upvotes: 2

Views: 109

Answers (1)

ebarr
ebarr

Reputation: 7842

You just need to add another dimension on to I, such that you can broadcast r properly:

result = r > I.reshape(I.shape[0],I.shape[1],1)

e.g.

In [41]: r>I.reshape(2,5,1)
Out[41]: 
array([[[False, False,  True],
        [False,  True,  True],
        [False, False, False],
        [False, False,  True],
        [False,  True,  True]],

       [[False,  True,  True],
        [False, False, False],
        [False, False,  True],
        [False,  True,  True],
        [False, False, False]]], dtype=bool)

Upvotes: 1

Related Questions