Home > Software engineering >  NumPy 2D array boolean indexing with each axis
NumPy 2D array boolean indexing with each axis

Time:11-04

I created 2D array and I did boolean indexing with 2 bool index arrays. first one is for axis 0, next one is for axis 1.

I expected that values on cross True and True from each axis are selected like Pandas. but the result is not.

I wonder how it works that code below. and I want to get the link from official numpy site describing this question.

Thanks in advance.

a = np.arange(9).reshape(3,3)
a
----------------------------
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
a[ [True, False, True], [True, False, True] ]
--------------------------
array([0, 8])

My expectation is [0, 6, 2, 8]. (I know how to get the result that I expect.)

CodePudding user response:

In [20]: a = np.arange(9).reshape(3,3)

If the lists are passed to ix_, the result is 2 arrays that can be used, with broadcasting to index the desired block:

In [21]: np.ix_([True, False, True], [True, False, True] )
Out[21]: 
(array([[0],
        [2]]),
 array([[0, 2]]))
In [22]: a[_]
Out[22]: 
array([[0, 2],
       [6, 8]])

This isn't 1d, but can be easily raveled.

Trying to make equivalent boolean arrays does not work:

In [23]: a[[[True], [False], [True]], [True, False, True]]
Traceback (most recent call last):
  File "<ipython-input-23-26bc93cfc53a>", line 1, in <module>
    a[[[True], [False], [True]], [True, False, True]]
IndexError: too many indices for array: array is 2-dimensional, but 3 were indexed

Boolean indexes must be either 1d, or nd matching the target, here (3,3).

In [26]: np.array([True, False, True])[:,None]& np.array([True, False, True])
Out[26]: 
array([[ True, False,  True],
       [False, False, False],
       [ True, False,  True]])

CodePudding user response:

What you want is consecutive slices: a[[True, False, True]][:,[True, False, True]]

a = np.arange(9).reshape(3,3)
x = [True, False, True]
y = [True, False, True]
a[x][:,y]

as flat array

a[[True, False, True]][:,[True, False, True]].flatten(order='F')

output: array([0, 6, 2, 8])

alternative

NB. this requires arrays for slicing

a = np.arange(9).reshape(3,3)
x = np.array([False, False, True])
y = np.array([True, False, True])
a.T[x&y[:,None]]

output: array([0, 6, 2, 8])

  • Related