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