gcornelis
gcornelis

Reputation: 51

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).

Upvotes: 5

Views: 2081

Answers (3)

Tonechas
Tonechas

Reputation: 13723

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_.

Upvotes: 8

oppressionslayer
oppressionslayer

Reputation: 7204

You can do it like this and your list idea works perfectly with it. In delete, you can pass a list instead of just 2

q = 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]])

np.delete(q,2, axis=1)[np.array([0,1,4])]                                                                                                                                           

array([[11, 12, 14, 15],
       [21, 22, 24, 25],
       [51, 52, 54, 55]])

Upvotes: 0

sacuL
sacuL

Reputation: 51335

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]])

Upvotes: 5

Related Questions