Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python tilde unary operator as negation numpy bool array

Should be a simple question, but I'm unable to find an answer anywhere. The ~ operator in python is a documented as a bitwise inversion operator. Fine. I have noticed seemingly schizophrenic behavior though, to wit:

~True -> -2 ~1 -> -2 ~False -> -1 ~0 -> -1 ~numpy.array([True,False],dtype=int) -> array([-2,-1]) ~numpy.array([True,False],dtype=bool) -> array([False,True]) 

In the first 4 examples, I can see that python is implementing (as documented) ~x = -(x+1), with the input treated as an int even if it's boolean. Hence, for a scalar boolean, ~ is not treated as a logical negation. Not that the behavior is identical on a numpy array defined with boolean values by with an int type.

Why does ~ then work as a logical negation operator on a boolean array (Also notice: ~numpy.isfinite(numpy.inf) -> True?)?

It is extremely annoying that I must use not() on a scalar, but not() won't work to negate an array. Then for an array, I must use ~, but ~ won't work to negate a scalar...

like image 745
Dr. Andrew Avatar asked Nov 28 '12 08:11

Dr. Andrew


People also ask

How do you invert a Boolean array in Python?

We can also use the Tilde operator (~) also known as bitwise negation operator in computing to invert the given array. It takes the number n as binary number and “flips” all 0 bits to 1 and 1 to 0 to obtain the complement binary number.

What is tilde Numpy?

The bitwise operator ~ (pronounced as tilde) is a complement operator. It takes one bit operand and returns its complement. If the operand is 1, it returns 0, and if it is 0, it returns 1.

How do you use the tilde operator in Python?

Python's Tilde ~n operator is the bitwise negation operator: it takes the number n as binary number and “flips” all bits 0 to 1 and 1 to 0 to obtain the complement binary number. For example, the tilde operation ~1 becomes 0 and ~0 becomes 1 and ~101 becomes 010 .


1 Answers

not is implemented through the __nonzero__ special method, which is required to return either True or False, so it can't give the required result. Instead the ~ operator is used, which is implemented through the __not__ special method. For the same reason, & and | are used in place of and and or.

PEP 335 aimed to allow overloading of boolean operators but was rejected because of excessive overhead (it would e.g. complicate if statements). PEP 225 suggests a general syntax for "elementwise" operators, which would provide a more general solution, but has been deferred. It appears that the current situation, while awkward, is not painful enough to force change.

np.isfinite when called on a scalar returns a value of type np.bool_, not bool. np.bool_ is also the type you get when extracting a scalar value from an array of bool dtype. If you use np.True_ and np.False_ in place of True and False you will get consistent behaviour under ~.

like image 71
ecatmur Avatar answered Oct 18 '22 09:10

ecatmur