Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a grid of a matrix via logical indexing in Numpy

I'm trying to rewrite a function using numpy which is originally in MATLAB. There's a logical indexing part which is as follows in MATLAB:

X = reshape(1:16, 4, 4).';
idx = [true, false, false, true];
X(idx, idx)

ans =

     1     4
    13    16

When I try to make it in numpy, I can't get the correct indexing:

X = np.arange(1, 17).reshape(4, 4)
idx = [True, False, False, True] 
X[idx, idx]
# Output: array([6, 1, 1, 6])

What's the proper way of getting a grid from the matrix via logical indexing?

like image 823
petrichor Avatar asked Jun 27 '13 06:06

petrichor


People also ask

What is Boolean indexing in Python NumPy?

We can also index NumPy arrays using a NumPy array of boolean values on one axis to specify the indices that we want to access. multi_arr = np.arange(12).reshape(3,4) This will create a NumPy array of size 3x4 (3 rows and 4 columns) with values from 0 to 11 (value 12 not included).

Can you index a NumPy array?

Array indexing is the same as accessing an array element. You can access an array element by referring to its index number. The indexes in NumPy arrays start with 0, meaning that the first element has index 0, and the second has index 1 etc.

What is the purpose of NumPy Meshgrid () in Python?

The numpy. meshgrid function is used to create a rectangular grid out of two given one-dimensional arrays representing the Cartesian indexing or Matrix indexing.


3 Answers

You could also write:

>>> X[np.ix_(idx,idx)]
array([[ 1,  4],
       [13, 16]])
like image 167
Amro Avatar answered Oct 10 '22 08:10

Amro


In [1]: X = np.arange(1, 17).reshape(4, 4)

In [2]: idx = np.array([True, False, False, True])  # note that here idx has to
                                                    # be an array (not a list)
                                                    # or boolean values will be 
                                                    # interpreted as integers

In [3]: X[idx][:,idx]
Out[3]: 
array([[ 1,  4],
       [13, 16]])
like image 22
root Avatar answered Oct 10 '22 07:10

root


In numpy this is called fancy indexing. To get the items you want you should use a 2D array of indices.

You can use an outer to make from your 1D idx a proper 2D array of indices. The outers, when applied to two 1D sequences, compare each element of one sequence to each element of the other. Recalling that True*True=True and False*True=False, the np.multiply.outer(), which is the same as np.outer(), can give you the 2D indices:

idx_2D = np.outer(idx,idx)
#array([[ True, False, False,  True],
#       [False, False, False, False],
#       [False, False, False, False],
#       [ True, False, False,  True]], dtype=bool)

Which you can use:

x[ idx_2D ]
array([ 1,  4, 13, 16])

In your real code you can use x=[np.outer(idx,idx)] but it does not save memory, working the same as if you included a del idx_2D after doing the slice.

like image 2
Saullo G. P. Castro Avatar answered Oct 10 '22 08:10

Saullo G. P. Castro