I'm afraid that you have to do put using one-d indices. But you do *not* have to try to ravel the source. I.e., the first arg is just the name of the array.
from Numeric import * x=array([[1,2,3],[4,5,6]]) x
array([[1, 2, 3], [4, 5, 6]])
array([[100, 2, 3], [ 4, 200, 6]])
-----Original Message----- From: Huaiyu Zhu [mailto:firstname.lastname@example.org] Sent: Friday, August 17, 2001 11:36 PM To: Paul F. Dubois Cc: John J. Lee Subject: RE: [Numpy-discussion] Subarray with with arbitrary index?
Thanks, John and Paul. That is what I was looking for.
It did not occur to me to look for verbs put and take, rather than words line sub- index, slice and so on. Maybe puting some of these words in the manual could help people doing a search?
Now that this made the most costly part of my program about seven times faster, other problems become more prominent. One of such question is: How do we do it on more than one axis?
Suppose a is a 2d array. Then put(a[1,:], b, c) works, but put(a[:,1], b, c) complains about the first argument not a continuous array. Doing transpose does not help. So do I guess it right that this is implemented only in the representation of a linear array?
If so, there would be no hope of using put(a, ([2, 4], [1,2]), v) or even more exotic ones like using += on an arbitray subgrid?
On Fri, 17 Aug 2001, Paul F. Dubois wrote:
John is right:
a=Numeric.arange(8) b=Numeric.array([2,3,5]) c=Numeric.arange(3)+100 Numeric.put(a,b,c) print a
[ 0 1 100 101 4 102 6 7]
Thanks for pointing out that I had left allclose out of the Numeric
the manual. I did it in the MA part and then forgot. I'm fixing it
There are changenotes at source forge that are sometimes ahead of the manual.
-----Original Message----- From: email@example.com [mailto:firstname.lastname@example.org]On Behalf Of John J. Lee Sent: Friday, August 17, 2001 6:36 AM To: Huaiyu Zhu Cc: email@example.com Subject: Re: [Numpy-discussion] Subarray with with arbitrary index?
On Thu, 16 Aug 2001, Huaiyu Zhu wrote:
Is it possible to assign to a subarray with arbitrary index?
Suppose I have three arrays
a = arange(8) b = array([2, 3, 5]) c = arange(3)+100
I want a function f, such that calling f(a, b, c) would change a to
[0 1 100 101 4 102 6 7]
f = Numeric.put f(a, b, c)
put used to be in Python, but it's been in C since some release
I have a sinking feeling that I must have missed something (no
here to check it works)...
BTW, a week ago I noticed that I had reinvented the wheel in
an uglier and less efficient form, Numeric.allclose (hope I got the
right). As far as I can see, it isn't listed in the manual. Did I
it? All it would need is the docstring copying over.
Numpy-discussion mailing list Numpyfirstname.lastname@example.org http://lists.sourceforge.net/lists/listinfo/numpy-discussion
I recently discovered the "clip()" function, and thought it was just what I'd been wanting, because I need to do that a lot, and it provided a nice notation, and I was hoping speed improvement over a couple of where() statements.
I did some experiments, and discovered that it was, in fact, slower than the where statements, and that the fastest way to do it is to use two putmask() calls. (note: this changes the array in place, rather than creating a new one)
The reason it is not faster is because it is written in Python, calling choose(), similarly to how where() does. I decided that I could use a fast version, so I set out to write one in C, resulting in the following questions:
A) How do I loop through all the elements of a discontiguous array of arbitraty dimensions? If I knew the rank ahead of time, I could just nest some for loops and use the strides values. Not knowing before hand, it seems that I should be able to do some nesting of loops using nd and dimensions, but I can't seem to work it out. Someone must have come up with a nifty way to do this. Is there an existing macro or function to do it?
B) How can I write a function that can act on any of the NumPy data types? I currently have it written to only work with contiguous Float arrays, which is what i need at the moment, but I'd much rather have one for the general case.
C) I'd also like any feedback on other elements of my code (enclosed with this email). A few comments on what the function (I've called it fastclip) is supposed to do:
changes the array, A, in place, so that all the elements less than min are replaced by min, and all the elements greater that max are replaced by max.
min and max can be either scalars, or anything that can be converted to an array with the same number of elements as A (using PyArray_ContiguousFromObject() ). If min and/or max is an array, than the coresponding elements are used. This allows, among other things, a way to clip to just a min or max value by calling it as: fastclip(A,A,max) or fastclip(A,min,A).
I wrote a little test script to benchmark the function, and it is much faster that the alternatives that I have thought of:
#!/usr/bin/env python # testing speed of where vs clip vs fastclip
from Numeric import * from RandomArray import uniform from NumericExtras import fastclip import time
n = 5000
a = uniform(0,100,(n,)) b = uniform(0,100,(n,)) c = uniform(0,100,(n,))
min = 20.0 max = 80.0
print "n = %i"%(n,)
start = time.clock() for i in range(100): a = clip(a,min,max) print "clip took %f seconds"%(time.clock()-start)
start = time.clock() for i in range(100): putmask(a,a < min,min) putmask(a,a > max,max) print "putmask took %f seconds"%(time.clock()-start)
start = time.clock() for i in range(100): fastclip(a,min,max) print "fastclip took %f seconds"%(time.clock()-start)
Here are some results:
n = 50 clip took 0.020000 seconds putmask took 0.050000 seconds fastclip took 0.010000 seconds
n = 5000 clip took 0.300000 seconds putmask took 0.230000 seconds fastclip took 0.030000 seconds
As expected the large the array is, the better the improvement.
I'd love to here any feedbackyou can give me: I've new to writing Python extensions, using the Numeric API, and C itself, for that matter.
"CB" == Chris Barker email@example.com writes:
I wrote my own specialized clip function too, only for 'f' and 'i' types, and only for contiguous arrays....
CB> A) How do I loop through all the elements of a discontiguous CB> array of arbitraty dimensions? If I knew the rank ahead of time, CB> I could just nest some for loops and use the strides CB> values. Not knowing before hand, it seems that I should be able CB> to do some nesting of loops using nd and dimensions, but I CB> can't seem to work it out. Someone must have come up with a nifty CB> way to do this. Is there an existing macro or function to do it?
Never done this in C for numpy yet, but I normally program this along the following lines:
n=[2,3,2,3] x=[0,0,0,0] while 1: print x i=len(n)-1 while i>=0 and x[i]+1==n[i]: x[i]=0 i=i-1 if i<0: break x[i]=x[i]+1
It is always going to be slower than the straight loop for contiguous arrays. So if you want to do it properly, you'd have to check whether the array is contiguous, and if it is, use the fast way.