Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slicing non-continous indexes in 2d Numpy array

I have a matrix, i.e. 2D numpy array and would like to be able to slice out non-continuous parts of it. For example with the following matrix

[[11 12 13 14 15]
 [21 22 23 24 25]
 [31 32 33 34 35]
 [41 42 43 44 45]
 [51 52 53 54 55]]

i would like to be able to extract, say

[[11 12 14 15]
 [21 22 24 25]
 [51 52 54 55]]

Is there a way to do this? I can easily extract continuous slice, for example matrix[0:2,0:3] would return

[[11 12 13]
 [21 22 23]

but not sure how to extract non-continuous. I read about using np.r_[], which works if used on one dimension only, but not on both.

The solution would need to be scalable as well as it would have to be used on large matrices with many non-continuous indexes (which I was thinking would be passed as list).

like image 806
gcornelis Avatar asked Mar 03 '23 00:03

gcornelis


2 Answers

You could use NumPy's advanced indexing and ix_() function to index the cross product of two 1-D sequences, the first one containing the indices of the rows you want to extract and the second one containing the indices of the columns.

In [24]: import numpy as np

In [25]: arr = np.asarray([[11, 12, 13, 14, 15], 
    ...:                   [21, 22, 23, 24, 25], 
    ...:                   [31, 32, 33, 34, 35], 
    ...:                   [41, 42, 43, 44, 45], 
    ...:                   [51, 52, 53, 54, 55]])
    ...: 

In [26]: rows = [0, 1, 4]

In [27]: cols = [0, 1, 3, 4]

In [28]: arr[np.ix_(rows, cols)]
Out[28]: 
array([[11, 12, 14, 15],
       [21, 22, 24, 25],
       [51, 52, 54, 55]])

It is worth pointing out that extending the approach above to index N-dimensional arrays is straightforward. You just need to pass further 1-D sequences to np.ix_.

like image 137
Tonechas Avatar answered Mar 05 '23 14:03

Tonechas


You can used chained indexing:

arr = np.array([[11, 12, 13, 14, 15],
       [21, 22, 23, 24, 25],
       [31, 32, 33, 34, 35],
       [41, 42, 43, 44, 45],
       [51, 52, 53, 54, 55]])

In [28]: arr[[0,1,4]][:, [0,1,3,4]]                                                                       
Out[28]: 
array([[11, 12, 14, 15],
       [21, 22, 24, 25],
       [51, 52, 54, 55]])
like image 29
sacuL Avatar answered Mar 05 '23 16:03

sacuL