extracting values from an array
Hi, I have a simple problem of extracting a subarray from a bigger one, for which I don't find an elegant/easy solution. I tried using searchsorted, or other tricks but I always end up with many "if" statements, testing all cases (also because searchsorted does not work on arrays which are sorted in decreasing order). There must be an elegant solution but I cannot find it. ==> I have one array of floats which has e.g. regular steps (as produced by arange) but can either be decreasing or increasing as for: x = arange(0.,1.,0.1) ## or x = arange(0.,1.,0.1) I also have another "data" y array, which has the same length than x. And I would like to extract from these arrays the subarrays, corresponding to the range x1  x2, going from x1, to x2. The output array should have its first element starting from the element in x closest to x1 (and in the range defined by x1, x2), and then going towards x2, for all cases (decreasing or increading order for x, and x1>=x2 or x1<=x2). So here is the output I would like to get in 3 different simple examples: ### Increasing order in x, and x1 <= x2 : x = arange(0.,1.,0.1) x1 = 0.1 x2 = 0.55 ### the output I would like is simply: array([ 0.1, 0.2, 0.3, 0.4, 0.5]) ### decreasing order in x, and x1 <= x2 : x = arange(0.,1.,0.1) x1 = 0.55 x2 = 0.1 ### I would like is then: array([ 0.5, 0.4, 0.3, 0.2, 0.1]) ### decreasing order in x, and x1 >= x2 : x = arange(0.,1.,0.1) x1 = 0.1 x2 = 0.55 ### I would like is then: array([ 0.1, 0.2, 0.3, 0.4, 0.5]) etc.... And it should work if both x1, and x2 are outside the given range provided in x (output should be an empty array) Note that I also need to extract the corresponding subarray from the data array (same indices as the one I extract from x). I hope this is clear. It is a very simple problem but I cannot see a simple solution without involving lots of stupid "if". It would be great if these "if" statements were hidden in some efficient numpy tricks/functions. thanks for any input. Eric
Hi Eric, Here are ways of doing this. starting with import numpy as N On 12/28/06, Eric Emsellem <emsellem@obs.univlyon1.fr> wrote:
### Increasing order in x, and x1 <= x2 : x = arange(0.,1.,0.1) x1 = 0.1 x2 = 0.55 ### the output I would like is simply: array([ 0.1, 0.2, 0.3, 0.4, 0.5])
How about this? x=N.arange(0.,1.,0.1) x[ (x>=0.1) & (x<=0.55) ] ### decreasing order in x, and x1 <= x2 :
x = arange(0.,1.,0.1) x1 = 0.55 x2 = 0.1 ### I would like is then: array([ 0.5, 0.4, 0.3, 0.2, 0.1])
x=N.arange(0.,1.,0.1) N.sort( x[ (x<=0.1) & (x>=0.55) ] ) or x[(x<=0.1)&(x>=0.55)][::1] just reverses the returned array. ### decreasing order in x, and x1 >= x2 :
x = arange(0.,1.,0.1) x1 = 0.1 x2 = 0.55 ### I would like is then: array([ 0.1, 0.2, 0.3, 0.4, 0.5])
x=N.arange(0.,1.,0.1) x[ (x<=0.1) & (x>=0.55) ] A few comments because I'm not totally clear on what you want to do. (x<=0.1)&(x>=0.55) will give you a boolean array of the same length as x find((x<=0.1)&(x>=0.55)) will return the list of indices where the argument is true. Regards, Greg  Linux. Because rebooting is for adding hardware.
Hi Eric, Well I think that you have the parts that you need. Perhaps something like is what you want. Put x1 and x2 into an array and sort it then access it from the sorted array. x=N.arange(0.,1.,0.1); xs=sort(array([0.1, 0.55])); sort(x[(x >= xs[0] )&(x<=xs[1])]) returns: [0.5,0.4,0.3,0.2,0.1,] x=N.arange(0.,1.,0.1); xs=sort(array([0.1, 0.55])); sort(x[(x >= xs[0] )&(x<=xs[1])]) returns: [ 0.1, 0.2, 0.3, 0.4, 0.5,] Same code just different x and different limits going into xs. Cheers, Greg On 12/28/06, Eric Emsellem <emsellem@obs.univlyon1.fr> wrote:
Hi, thanks for the answer, but I guess my request was not clear. What I want is something which works in ALL cases so that
function(x, x1, x2) provides the output I mentioned... What you propose (as far as I can see) depends on the values of x1, x2, their order and the order of x (decreasing, increasing)...
if you have a hint on how to do this without TESTING how x is ordered (dec, inc) and which of x1 or x2 is larger... thanks
Eric
Greg Willden wrote:
Hi Eric, Here are ways of doing this. starting with import numpy as N
On 12/28/06, Eric Emsellem < emsellem@obs.univlyon1.fr> wrote:
### Increasing order in x, and x1 <= x2 : x = arange(0.,1.,0.1) x1 = 0.1 x2 = 0.55 ### the output I would like is simply: array([ 0.1, 0.2, 0.3, 0.4, 0.5])
How about this? x=N.arange(0.,1.,0.1) x[ (x>=0.1) & (x<= 0.55) ]
### decreasing order in x, and x1 <= x2 :
x = arange(0.,1.,0.1) x1 = 0.55 x2 = 0.1 ### I would like is then: array([ 0.5, 0.4, 0.3, 0.2, 0.1])
x=N.arange(0.,1.,0.1) N.sort( x[ (x<=0.1) & (x>=0.55) ] ) or x[(x<=0.1)&(x>= 0.55)][::1] just reverses the returned array.
### decreasing order in x, and x1 >= x2 :
x = arange(0.,1.,0.1) x1 = 0.1 x2 = 0.55 ### I would like is then: array([ 0.1, 0.2, 0.3, 0.4, 0.5])
x=N.arange(0.,1.,0.1) x[ (x<=0.1) & (x>=0.55) ]
A few comments because I'm not totally clear on what you want to do. (x<=0.1)&(x>=0.55) will give you a boolean array of the same length as x find((x<=0.1)&(x>=0.55)) will return the list of indices where the argument is true.
Regards, Greg
 Linux. Because rebooting is for adding hardware.

_______________________________________________ Numpydiscussion mailing list Numpydiscussion@scipy.orghttp://projects.scipy.org/mailman/listinfo/numpydiscussion
 ==================================================================== Eric Emsellem emsellem@obs.univlyon1.fr Centre de Recherche Astrophysique de Lyon 9 av. CharlesAndre tel: +33 (0)4 78 86 83 84 69561 SaintGenis Laval Cedex fax: +33 (0)4 78 86 83 86 France http://wwwobs.univlyon1.fr/eric.emsellem ====================================================================
_______________________________________________ Numpydiscussion mailing list Numpydiscussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpydiscussion
 Linux. Because rebooting is for adding hardware.
looks ok, except that I don't want to sort out the output but keep the right order depending on x0 and x1, so I have then to add the order I wish for the output array, maybe with something like: ## init x0 = 0.55 x1 = 0.1 min,max,step = 0., 1., 0.1 x=num.arange(min,max,step); ## getting the right output xs=sort(array([x0,x1])) x[(x >= xs[0]) & (x<=xs[1])][::num.sign(x1x0)*num.sign(step)] should work. I don't see a simpler way here... thanks to get me on track!!! Eric Greg Willden wrote:
Hi Eric, Well I think that you have the parts that you need. Perhaps something like is what you want. Put x1 and x2 into an array and sort it then access it from the sorted array.
x=N.arange(0.,1.,0.1); xs=sort(array([0.1, 0.55])); sort(x[(x >= xs[0] )&(x<=xs[1])])
returns: [0.5,0.4,0.3,0.2,0.1,]
x=N.arange(0.,1.,0.1); xs=sort(array([0.1, 0.55])); sort(x[(x >= xs[0] )&(x<=xs[1])])
returns: [ 0.1, 0.2, 0.3, 0.4, 0.5,]
 ==================================================================== Eric Emsellem emsellem@obs.univlyon1.fr Centre de Recherche Astrophysique de Lyon 9 av. CharlesAndre tel: +33 (0)4 78 86 83 84 69561 SaintGenis Laval Cedex fax: +33 (0)4 78 86 83 86 France http://wwwobs.univlyon1.fr/eric.emsellem ====================================================================
participants (2)

Eric Emsellem

Greg Willden