[Numpy-discussion] puzzle: generate index with many ranges

Raik Gruenberg raik.gruenberg at crg.es
Sun Feb 1 06:02:04 EST 2009


Beautiful! That should do the trick. Now let's see how this performs against the 
list comprehension...

Thanks a lot!
Raik

Rick White wrote:
> Here's a technique that works:
> 
> Python 2.4.2 (#5, Nov 21 2005, 23:08:11)
> [GCC 4.0.0 20041026 (Apple Computer, Inc. build 4061)] on darwin
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> import numpy as np
>  >>> a = np.array([0,4,0,11])
>  >>> b = np.array([-1,11,4,15])
>  >>> rangelen = b-a+1
>  >>> cumlen = rangelen.cumsum()
>  >>> c = np.arange(cumlen[-1],dtype=np.int32)
>  >>> c += np.repeat(a[1:]-c[cumlen[0:-1]], rangelen[1:])
>  >>> print c
> [ 4  5  6  7  8  9 10 11  0  1  2  3  4 11 12 13 14 15]
> 
> The basic idea is that the difference of your desired output from a  
> simple range is an array with a bunch of constant values appended  
> together, and that is what repeat() does.  I'm assuming that you'll  
> never have b < a.  Notice the slight ugliness of prepending the  
> elements at the beginning so that the cumsum starts with zero.   
> (Maybe there is a cleaner way to do that.)
> 
> This does create a second array (via the repeat) that is the same  
> length as the result.  If that uses too much memory, you could break  
> up the repeat and update of c into segments using a loop.  (You  
> wouldn't need a loop for every a,b element -- do a bunch in each  
> iteration.)
> 
> -- Rick
> 
> Raik Gruenberg wrote:
> 
>> Hi there,
>>
>> perhaps someone has a bright idea for this one:
>>
>> I want to concatenate ranges of numbers into a single array (for  
>> indexing). So I
>> have generated an array "a" with starting positions, for example:
>>
>> a = [4, 0, 11]
>>
>> I have an array b with stop positions:
>>
>> b = [11, 4, 15]
>>
>> and I would like to generate an index array that takes 4..11, then  
>> 0..4, then
>> 11..15.
>>
>> In reality, a and b have 10000+ elements and the arrays to be  
>> "sliced" are very
>> large so I want to avoid any for loops etc. Any idea how this could  
>> be done? I
>> thought some combination of *repeat* and adding of *arange* should  
>> do the trick
>> but just cannot nail it down.
>>
>> Thanks in advance for any hints!
>>
>> Greetings,
>> Raik
> 
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion at scipy.org
> http://projects.scipy.org/mailman/listinfo/numpy-discussion
> 
> 

-- 
________________________________

Dr. Raik Gruenberg
http://www.raiks.de/contact.html
________________________________



More information about the NumPy-Discussion mailing list