70

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?

Timothy Shields
  • 75,459
  • 18
  • 120
  • 173
user1595929
  • 1,284
  • 3
  • 13
  • 23

6 Answers6

115

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]])
JoshAdel
  • 66,734
  • 27
  • 141
  • 140
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.

mdml
  • 22,442
  • 8
  • 58
  • 66
12
print y[0:4:3,0:4:3]

is the shortest and most appropriate fix .

erip
  • 16,374
  • 11
  • 66
  • 121
Hima
  • 11,268
  • 3
  • 22
  • 31
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])

CT Zhu
  • 52,648
  • 17
  • 120
  • 133
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.

ali_m
  • 71,714
  • 23
  • 223
  • 298
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]]
Father Geppeto
  • 139
  • 1
  • 8