0

When using logical indexing on numpy arrays, different behaviours occur based on whether the indices were boolean or integer (1/0). This answer states that, as of Python 3.x,

True and False are keywords and will always be equal to 1 and 0.

Can someone explain what causes this behaviour?

MWE to replicate (Python 3.7.3, Numpy 1.16.3):

import numpy as np

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [True, True, True, True, True, False, False, False, False, False]
c = [1, 1, 1, 1, 1, 0, 0, 0, 0, 0]

npa = np.asarray(a)
npb = np.asarray(b)
npc = np.asarray(c)

print(npa[b])   # [0 1 2 3 4]
print(npa[npb]) # [0 1 2 3 4]
print(npa[c])   # [1 1 1 1 1 0 0 0 0 0]
print(npa[npc]) # [1 1 1 1 1 0 0 0 0 0]
bhnn
  • 225
  • 5
  • 17
  • 1
    `c` is just selecting the `a[0]` or `a[1]`. It's a regular numeric index, not boolean. In 'boolean' contexts, 0/1 have False/True meanings, but this isn't one of those. – hpaulj Mar 10 '20 at 16:26

1 Answers1

2

If we look at it like this:

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [True, True, True, True, True, False, False, False, False, True]
c = [1, 1, 1, 1, 1, 0, 0, 0, 0, -1]

npa = np.asarray(a)
npb = np.asarray(b)
npc = np.asarray(c)

print(npa[b])   # [0 1 2 3 4 9]
print(npa[npb]) # [0 1 2 3 4 9]
print(npa[c])   # [1 1 1 1 1 0 0 0 0 0 9]
print(npa[npc]) # [1 1 1 1 1 0 0 0 0 0 9]

We can see that b and npb are boolean masks that instruct which indices to choose and c and npc are actual indices to be taken from the given array.

This is mentioned in docs:

Boolean arrays used as indices are treated in a different manner entirely than index arrays ... Unlike in the case of integer index arrays, in the boolean case, the result is a 1-D array containing all the elements in the indexed array corresponding to all the true elements in the boolean array.

zipa
  • 27,316
  • 6
  • 40
  • 58