2
votes

Einstein summation (numpy.einsum) of boolean arrays in numpy doesn't produce expected results. Numpy.einsum function does logical operations on boolean arrays, which is questionable in the numeric contexts.

# summation of a boolean numpy array

x = numpy.array([True, False, True])

print(numpy.sum(x))
# output: 2

print(numpy.einsum('i->', x))
# output: True

For a boolean array x = [True, False, True], I expect that the summation of x is 2, and the result should not depend on the particular choice of the function. However, numpy.sum gave 2, and numpy.einsum gave True.

I am not sure whether I misunderstood something or there is some problem with my code. Any help is appreciated.

1
It's not obvious to me that 'sum' on a boolean array should produce a numeric result. Logical sum/and makes as much sense to me, maybe more. [email protected]([True,True,True]) produces a boolean True as well.hpaulj
it is my interpretation of a sentence appeared in python's documents, which says "In numeric contexts (for example when used as the argument to an arithmetic operator), they behave like the integers 0 and 1, respectively." (link docs.python.org/3.7/library/stdtypes.html). I am not 100% sure about the exact meaning of "numeric contexts". Not sure whether the following cases can be counted as the numeric contexts, np.array([True, False])**np.array([True]), np.array([True, False])/np.array([True]), and np.array([True, False])*np.array([True]). I think the question is too subjectiveyuyangtj

1 Answers

2
votes

The difference here is that sum casts the boolean into integers before summing, while einsum skips this step except if you specify it explicitly.

Try:

print(numpy.einsum('i->', x, dtype=int))