74

I'm pretty new in numpy and I am having a hard time understanding how to extract from a np.array a sub matrix with defined columns and rows:

Y = np.arange(16).reshape(4,4)

If I want to extract columns/rows 0 and 3, I should have:

[[0 3]
 [12 15]]

I tried all the reshape functions...but cannot figure out how to do this. Any ideas?

0

7 Answers 7

117

Give np.ix_ a try:

Y[np.ix_([0,3],[0,3])]

This returns your desired result:

In [25]: Y = np.arange(16).reshape(4,4)
In [26]: Y[np.ix_([0,3],[0,3])]
Out[26]:
array([[ 0,  3],
       [12, 15]])
Sign up to request clarification or add additional context in comments.

Comments

22

One solution is to index the rows/columns by slicing/striding. Here's an example where you are extracting every third column/row from the first to last columns (i.e. the first and fourth columns)

In [1]: import numpy as np
In [2]: Y = np.arange(16).reshape(4, 4)
In [3]: Y[0:4:3, 0:4:3]
Out[1]: array([[ 0,  3],
               [12, 15]])

This gives you the output you were looking for.

For more info, check out this page on indexing in NumPy.

1 Comment

I like this answer because of the notation's similarity to matlab's notation
12
print y[0:4:3,0:4:3]

is the shortest and most appropriate fix .

Comments

10

First of all, your Y only has 4 col and rows, so there is no col4 or row4, at most col3 or row3.

To get 0, 3 cols: Y[[0,3],:] To get 0, 3 rows: Y[:,[0,3]]

So to get the array you request: Y[[0,3],:][:,[0,3]]

Note that if you just Y[[0,3],[0,3]] it is equivalent to [Y[0,0], Y[3,3]] and the result will be of two elements: array([ 0, 15])

Comments

7

You can also do this using:

Y[[[0],[3]],[0,3]]

which is equivalent to doing this using indexing arrays:

idx = np.array((0,3)).reshape(2,1)
Y[idx,idx.T]

To make the broadcasting work as desired, you need the non-singleton dimension of your indexing array to be aligned with the axis you're indexing into, e.g. for an n x m 2D subarray:

Y[<n x 1 array>,<1 x m array>]

This doesn't create an intermediate array, unlike CT Zhu's answer, which creates the intermediate array Y[(0,3),:], then indexes into it.

Comments

0

This can also be done by slicing: Y[[0,3],:][:,[0,3]]. More elegantly, it is possible to slice arrays (or even reorder them) by given sets of indices for rows, columns, pages, et cetera:

r=np.array([0,3])
c=np.array([0,3])
print(Y[r,:][:,c]) #>>[[ 0  3][12 15]]

for reordering try this:

r=np.array([0,3])
c=np.array([3,0])
print(Y[r,:][:,c])#>>[[ 3  0][15 12]]

Comments

0

Extracting submatrices is possible using two methods, which have already been suggested in the existing answers. Here is a summary using this matrix:

Y: array([[4, 1, 4, 3, 1],
          [3, 1, 2, 3, 1],
          [4, 3, 2, 2, 4],
          [2, 4, 3, 2, 3],
          [2, 1, 4, 4, 3]])
  1. Your submatrix is a contiguous rectangular region of the original matrix, then use regular range indexing. E.g to extract the region at intersection of rows 3,4 and cols 2,3:
    enter image description here

    >>> Y[3:, 2:4]
    >>> array([[3, 2],
    >>>        [4, 4]])
    
  2. You submatrix is not a contiguous region, some rows and/or columns have been removed within this region, then you must build a mesh of valid cells, and use it as a mask. Fortunately this is the purpose of numpy:ix_, e.g. to extract the intersection of rows 1, 3 and columns 0,3:
    enter image description here

    >>> np.ix_((1,3), (0,3))
    >>> (array([[1],
    >>>         [3]]),
    >>>  array([[0, 3]]))
    >>>
    >>> Y[np.ix_((1,3), (0,3))]
    >>> array([[3, 3],
    >>>        [2, 2]])
    

Note np.ix_((1,3), (0,3)) is strictly equivalent to [[1],[3]],[0, 3], so you can use it directly instead of calling the meshgrid builder:

>>> Y[[[1],[3]],[0, 3]]
>>> array([[3, 3],
>>>        [2, 2]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.