I'm quite new to Python. I was reading and testing codes in the Numpy official documentation. At the end of part 2.6.2 (Indexing with Boolean Arrays) there's an example that returns a weird answer. Funny though, the documentation says " a weird thing to do".
a = np.arange(12).reshape(3, 4)
b1 = np.array([False, True, True])
b2 = np.array([True, False, True, False])
a[b1, b2]
I think it should return the following answer (or sth like that):
array([ 4, 6, 8, 10])
but it returns:
array([ 4, 10])
here is a logic map. Am I wrong somehow? Logic Map
CodePudding user response:
As the docs pointed out, it is a weird thing to do.
In practice, you would use different methods for each of the results that you want.
(see below)
As @Michael pointed out in the comments, passing two boolean arrays converts them into index numbers first:
a[b1, b2]
|
V
a[np.flatnonzero(b1), np.flatnonzero(b2)]
|
V
a[(array([1, 2]), array([0, 2]))]
Perhaps it is implemented this way (and not like a[np.ix_(b1, b2)]
) by the analogy of having only one array for indexing. For example, when you simply do a[b1]
, this might be happening internally: a[np.flatnonzero(b1)]
.
And for more than 1 array this is simply the same mechanic.
1. To get your expected output:
See this answer. In your case it would be:
a[b1][:, b2]
produces
array([[ 4, 6],
[ 8, 10]])
which you can then .flatten()
:
array([ 4, 6, 8, 10])
Or:
You can use np.ix_
:
np.ix_(b1, b2)
produces a tuple of arrays:
(array([[1],
[2]]),
array([[0, 2]]))
which can be used to get the same result:
a[np.ix_(b1, b2)].flatten()
2. To get array([ 4, 10])
in a non-weird way:
Use integer array indexing explicitly:
a[[1, 2], [0, 2]]