[Numpy-discussion] Selected and altering a submatrix

Robert Kern robert.kern at gmail.com
Mon Jan 29 23:09:59 CST 2007


Steve Lianoglou wrote:
> ===
> import numpy as N
> mat = N.zeros((10,10))
> rows = [0,1,2]
> cols = [4,5,6]
> 
> for row in rows:
>     mat[row,cols] += 1
> 
> ====
> 
> I found something on the lists from a few years back that was in  
> reference to numeric or numarray that suggested doing some gymnastics  
> with take/put, but it still seemed as if there was no way to slice  
> out this view of a matrix w/o making a copy.

Actually, it's pretty easy these days to handle the general case (the other
posts have sufficiently covered the case where your rows and columns are
representable by slices). Just make sure that the index arrays row and cols are
the right shape. Since you want mat[rows, cols] to be an array of shape
(len(rows), len(cols)), each index should be of that shape *or* they need to
broadcast to that shape. Thus, you could either have this:

  rows = [[0, 0, 0],
          [1, 1, 1],
          [2, 2, 2]]
  cols = [[4, 5, 6],
          [4, 5, 6],
          [4, 5, 6]]

or you could have this:

  rows = [[0], [1], [2]]
  cols = [4, 5, 6]

Here is a slightly more complicated example:


In [25]: from numpy import *

In [26]: A = arange(6*6).reshape((6,6))

In [27]: rows = array([0, 2, 3])[:,newaxis]

In [28]: cols = array([5, 4, 1])

In [29]: A[rows, cols]
Out[29]:
array([[ 5,  4,  1],
       [17, 16, 13],
       [23, 22, 19]])

In [30]: A
Out[30]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23],
       [24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35]])

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth."
  -- Umberto Eco


More information about the Numpy-discussion mailing list