Reputation: 51
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
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
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
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