assigning to submatrix
If I have a large matrix, say a = zeros( (20,20) ) and a small matrix b = ones( 3,4 ) and a list of row indices and a list of col indices rind = [2,4,9,15] cind = [1,4,12] what is the best way to assign the submatrix to a[rind,cind]. I understand this is possible in numarray, but is there a good way to do it in Numeric? In matlab, you could do a(rind, cind)=b; Is there some reshape, put magic I can do to make this efficient in Numeric? Thanks, John Hunter
-----Original Message----- From: numpy-discussion-admin@lists.sourceforge.net [mailto:numpy-discussion-admin@lists.sourceforge.net]On Behalf Of John Hunter Sent: Tuesday, July 29, 2003 12:30 PM To: Numerical Python Discussion Subject: [Numpy-discussion] assigning to submatrix
If I have a large matrix, say
a = zeros( (20,20) )
and a small matrix
b = ones( 3,4 )
and a list of row indices and a list of col indices
rind = [2,4,9,15] cind = [1,4,12]
what is the best way to assign the submatrix to a[rind,cind]. I understand this is possible in numarray, but is there a good way to do it in Numeric?
In matlab, you could do a(rind, cind)=b; Is there some reshape, put magic I can do to make this efficient in Numeric?
Thanks, John Hunter
------------------------------------------------------- This SF.Net email sponsored by: Free pre-built ASP.NET sites including Data Reports, E-commerce, Portals, and Forums are available now. Download today and enter to win an XBOX or Visual Studio .NET. http://aspnet.click-url.com/go/psa00100003ave/direct;at.aspnet_072 303_01/01 _______________________________________________ Numpy-discussion mailing list Numpy-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/numpy-discussion
If I have a large matrix, say
a = zeros( (20,20) )
and a small matrix
b = ones( 3,4 )
and a list of row indices and a list of col indices
rind = [2,4,9,15] cind = [1,4,12]
what is the best way to assign the submatrix to a[rind,cind]. I understand this is possible in numarray, but is there a good way to do it in Numeric?
In matlab, you could do a(rind, cind)=b; Is there some reshape, put magic I can do to make this efficient in Numeric?
Thanks, John Hunter
Note that numarray doesn't do the same thing as matlab in this regard. In particular, the expression a[rind, cind] = b would fail since it is expecting an array on the right hand side that is the same shape as the index arrays. The assignment here is taken to mean: a[rind[0], cind[0]] = b[0] a[rind[1], cind[1]] = b[1] etc. not: a[rind[0], cind[0]] = b[0,0] etc. To do what you want doesn't currently have any atomic operation in numarray. Is this widely used? At the moment I think you would be forced to iterate over one dimension. E.g., for i in range(len(rind)): a[cind, rind[i]] = b[:, i] [Note that I reordered the index arrays to match b; I wasn't sure what was intended] There may be some clever way to avoid the explicit looping. Nothing prevents the addition of such a feature to numarray (other than work!), but it would likely have to use a function. I think the current defintion of how multiple index puts and takes work with brackets is more useful than the interpretation you are using and isn't likely to change. Perry
"Perry" == Perry Greenfield <perry@stsci.edu> writes:
Perry> [Note that I reordered the index arrays to match b; I Perry> wasn't sure what was intended] Yep, I think that was a blooper on my part; to be precise, here is the matlab code a = zeros( 8,8 ); b = ones( 3,4 ); rind = [2,4,6]; cind = [1,4,5,6]; a(rind, cind) = b; and the equivalent python from Numeric import * a = zeros( (8,8) ) b = ones( (3,4) ) rind = [1,3,5] cind = [0,3,4,5] for ia, ib in zip(rind, range(len(rind))): for ja, jb in zip(cind, range(len(cind))): a[ia,ja] = b[ib,jb] print a And the question is: is there a good way to avoid the double loop using Numeric? Thanks, John
for ia, ib in zip(rind, range(len(rind))): for ja, jb in zip(cind, range(len(cind))): a[ia,ja] = b[ib,jb] print a
And the question is: is there a good way to avoid the double loop using Numeric?
Thanks, John
At least one way, but it isn't particularly convenient or pretty (though the ugly details could be hidden in a function). (and I warn you, I haven't tested this, but something like this ought to work) # produce all possible combinations of rind and cind as # indices into an equivalent flattened for a indices = add.outer(rind*a.shape[1],cind).flat put(a, indices, b.flat) One can do this for numarray as well in a bit more straightforward way (depending on your view) [again, untested] t = ones(b.shape) a[multiply.outer(rind,t[0]),cind*t] = b In other words, this constructs two index arrays, one for each dimension, each with the same shape as the source array, b where the locations in that array correspond to the desired index in the source array. For numeric, you must do all the selection on a 1-d array, hence the index arithmetic. Perry
participants (2)
-
John Hunter
-
Perry Greenfield