107

Can I use ~A to invert a numpy array of booleans, instead of the rather awkward functions np.logical_and() and np.invert()?

Indeed, ~ seems to work fine, but I can't find it in any nympy reference manual, and - more alarmingly - it certainly does not work with scalars (e.g. bool(~True) returns True !), so I'm a little bit worried ...

2

2 Answers 2

81

short answer: YES

Ref:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.invert.html

Notice:

Computes the bit-wise NOT of the underlying binary representation of the integers in the input arrays. This ufunc implements the C/Python operator ~.

and

bitwise_not is an alias for invert:

>> np.bitwise_not is np.invert
>> True
Sign up to request clarification or add additional context in comments.

3 Comments

However, be careful that this will not work with an array of 0's and 1's! It will only work with an array of booleans. If you need to handle that kind of flexibility, use numpy.logical_not instead
@tvt173 Yes, boolean not and logic not are always different. Both the question and the answer are about boolean not. Thanks for reminding anyway.
Note that, this actually only works when the array's dtype=bool. I just stumbled upon the edge case of an array full of True and False objects with dtype=object. These are converted like ~True => -2 and ~False => -1. See the duplicate target linked in the question comments.
9

You can use the tilde if the array's dtype is boolean and you are sure that this won't change as the software matures. However, np.logical_not has two advantages:

  • It also works for object arrays, which can easily show up if np.nans or other objects make it into your array.
  • Its meaning is clear to anyone with a little background in logics.

There is also np.invert but it doesn't work with object arrays and the word is ambiguous.

~np.array([False, True], dtype=bool)
Out[7]: array([ True, False])

~np.array([False, True], dtype=object)
Out[9]: array([-1, -2], dtype=object)

np.invert([True, False])
Out[4]: array([False,  True])

np.invert((np.array([True, False], dtype=object)))
Out[5]: array([-2, -1], dtype=object)

np.logical_not(np.array([False, True], dtype=bool))
Out[8]: array([ True, False])

np.logical_not(np.array([False, True], dtype=object))
Out[10]: array([True, False], dtype=object)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.