Inverting a numpy boolean array using ~
Asked Answered
G

2

99

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 ...

Ghibelline answered 5/12, 2012 at 17:15 Comment(2)
See #13601488Sunken
Does this answer your question? python tilde unary operator as negation numpy bool arrayAntakiya
H
76

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
Helminthology answered 6/3, 2014 at 12:47 Comment(3)
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 insteadHigbee
@Higbee Yes, boolean not and logic not are always different. Both the question and the answer are about boolean not. Thanks for reminding anyway.Helminthology
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.Gervase
G
5

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)
Gervase answered 3/1, 2023 at 18:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.