General Numerical Python question

Scott Ransom ransom at physics.mcgill.ca
Sat Oct 18 11:29:38 EDT 2003


mjackson at alumni.caltech.edu (Mark Jackson) wrote in message news:<bmp9us$oa8$1 at news.wrc.xerox.com>...
> mcrider at bigfoot.com (2mc) writes:
> > Michael Ressler <ressler at cheetah.jpl.nasa.gov> wrote in message news:<slrnboqrh1.6mk.ressler at cheetah.jpl.nasa.gov>...
> > > Another example of thinking things differently is suppose you have a
> > > vector where the values are randomly positive or negative. Suppose for
> > > reasons known only to you, you want to replace the negative values
> > > with the sqrt of their absolute values. With Numeric, no loops are
> > > involved.
> > > 
> > > from Numeric import *
> > > a=array([1.,2.,-3.,4.,-5.,6.,-7.,-8.,9.])	# make up an array
> > > idx=nonzero(a<0)			# indexes of the negative values
> > > sqrs=sqrt(abs(take(a,idx)))		# get the sqrts of neg elements
> > > put(a,idx,sqrs)				# put them back into a
> > > print a					# works!  
> > > 
> > > You can make the whole thing a one-liner if you want to get carried
> > > away with it. It's too bad "nonzero" isn't called "whereis" or
> > > something like that - it would make the idx= line more obvious.
> > > 
> > > Mike
> > 
> > I think I'm finally getting a handle on this.  So, my thanks to
> > everyone who has so graciously helped me out with their suggestions.
> > 
> > How would you handle the above if "a" were a 2d array since "nonzero"
> > only works on 1d arrays?  Could you have used the "nonzero" function
> > on a "vertical" slice of the array (from the perspective of an array
> > of rows and columns - a vertical slice being the data in the column)?
> 
> I'm very new at this myself (currently porting some Fortran code to
> Numeric) but I believe that Numeric.putmask is your friend here:
> 
> >>> a=Numeric.array([i*(-1)**i for i in range(20)],Numeric.Float)
> >>> b=a.resize((4,5))
> >>> b
> array([[  0.,  -1.,   2.,  -3.,   4.],
>        [ -5.,   6.,  -7.,   8.,  -9.],
>        [ 10., -11.,  12., -13.,  14.],
>        [-15.,  16., -17.,  18., -19.]])
> >>> mask = b<0
> >>> mask
> array([[0, 1, 0, 1, 0],
>        [1, 0, 1, 0, 1],
>        [0, 1, 0, 1, 0],
>        [1, 0, 1, 0, 1]])
> >>> Numeric.putmask(b, mask, Numeric.sqrt(abs(b)))
> >>> b
> array([[  0.        ,   1.        ,   2.        ,   1.73205081,   4.        ],
>        [  2.23606798,   6.        ,   2.64575131,   8.        ,   3.        ],
>        [ 10.        ,   3.31662479,  12.        ,   3.60555128,  14.        ],
>        [  3.87298335,  16.        ,   4.12310563,  18.        ,   4.35889894]])

Once again, this can be done in a single (easy-to-read) line using:

b = where(b<0, sqrt(fabs(b)), b)

where does all the masking and putmasking for you.

Scott




More information about the Python-list mailing list