Hi, I was just curious what the "correct" (fast) way to select and alter a submatrix. For example, say I have a 10x10 array and only want to add some number to the elements in the submatrix that consists of the [0,1,2] th rows, and [4,5,6]th colums. You can imagine that those rows/cols select a square in the top- middle of the 10x10 which I want to alter. The only way I can get this to work is if I iterate over the indices in one of the dimensions (say the rows) and use the column indices to slice out the relevant elements to add to .. is there a NumPy-thonic way to do this: === 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. Thanks, -steve
How about mat[0:3, 4:7] += 1 -Sebastian On 1/29/07, Steve Lianoglou <lists.steve@arachnedesign.net> wrote:
Hi,
I was just curious what the "correct" (fast) way to select and alter a submatrix.
For example, say I have a 10x10 array and only want to add some number to the elements in the submatrix that consists of the [0,1,2] th rows, and [4,5,6]th colums.
You can imagine that those rows/cols select a square in the top- middle of the 10x10 which I want to alter.
The only way I can get this to work is if I iterate over the indices in one of the dimensions (say the rows) and use the column indices to slice out the relevant elements to add to .. is there a NumPy-thonic way to do this:
=== 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.
Thanks, -steve _______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
How about mat[0:3, 4:7] += 1 -Sebastian On 1/29/07, Steve Lianoglou <lists.steve@arachnedesign.net> wrote:
Hi,
I was just curious what the "correct" (fast) way to select and alter a submatrix.
For example, say I have a 10x10 array and only want to add some number to the elements in the submatrix that consists of the [0,1,2] th rows, and [4,5,6]th colums.
You can imagine that those rows/cols select a square in the top- middle of the 10x10 which I want to alter.
The only way I can get this to work is if I iterate over the indices in one of the dimensions (say the rows) and use the column indices to slice out the relevant elements to add to .. is there a NumPy-thonic way to do this:
=== 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.
Thanks, -steve _______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
On 1/29/07, Steve Lianoglou <lists.steve@arachnedesign.net> wrote:
For example, say I have a 10x10 array and only want to add some number to the elements in the submatrix that consists of the [0,1,2] th rows, and [4,5,6]th colums.
Here's one way to do it: i,j = N.mgrid[0:3,4:7] mat[i,j] += 1
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
Hi all, Thank you for your replies ... my question was initially unclear in that I knew that using normal slicing would do the trick, but it was rather a list of indices that couldn't be represented as a slice that was bugging me. Luckily, Robert's solution solves this problem for the general case. Thanks for the help, -steve On Jan 30, 2007, at 12:09 AM, Robert Kern wrote:
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 _______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
participants (5)
-
Keith Goodman -
Robert Kern -
Sebastian Haase -
Sebastian Haase -
Steve Lianoglou