[SciPy-User] "inverting" an array

Justus Schwabedal jschwabedal at gmail.com
Tue Feb 4 15:59:06 EST 2014


Hi everyone,

I ran a test of which solution is faster.
For random integers, the repeat solution
wins, but for sparse vectors "a" Eric's solution
is actually faster!

Now, that's a suprise...

J


2014-02-04 <scipy-user-request at scipy.org>:

> Send SciPy-User mailing list submissions to
>         scipy-user at scipy.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         http://mail.scipy.org/mailman/listinfo/scipy-user
> or, via email, send a message with subject or body 'help' to
>         scipy-user-request at scipy.org
>
> You can reach the person managing the list at
>         scipy-user-owner at scipy.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of SciPy-User digest..."
>
>
> Today's Topics:
>
>    1. "inverting" an array (nicky van foreest)
>    2. Re: "inverting" an array (Warren Weckesser)
>    3. Re: "inverting" an array (Eric Hermes)
>    4. Re: "inverting" an array (nicky van foreest)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Tue, 4 Feb 2014 20:33:26 +0100
> From: nicky van foreest <vanforeest at gmail.com>
> Subject: [SciPy-User] "inverting" an array
> To: SciPy Users List <scipy-user at scipy.org>
> Message-ID:
>         <CAK_GA2EbBAKwVJ6K=
> h9M114ea2WcmuY-DZHmgjz-D22GT+6_rg at mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
>
> Hi,
>
> I am wondering whether a shortcut exists in numpy/scipy for the following
> problem.  The values in an array represent the number of customers that
> arrive in a certain time slot, e.g.,
>
> a = [0,4,7,3,1,5, 0,0,0,]
>
> means that in time slot 1 4 customers arrive, in time slot 2 seven arrive,
> and so on. Now I want to "invert" this array to compute the arrival time of
> the i-th customer. Thus, customer 2 arrives in time slot 1, customer 6 in
> time slot 2, and so on. For this problem I wrote the following function:
>
> a = [0,4,7,3,1,5, 0,0,0,]
> A = np.cumsum(a)
>
> def invert(A):
>     Ainv = np.empty(A[-1])
>     aprev=0
>     for i, a in enumerate(A):
>         Ainv[aprev:a] = i
>         aprev = a
>     return Ainv
>
>
> Ainv= invert(A)
>
> print a
> print A
> print Ainv
>
> The output is
>
> [0, 4, 7, 3, 1, 5, 0, 0, 0]
> [ 0  4 11 14 15 20 20 20 20]
> [ 1.  1.  1.  1.  2.  2.  2.  2.  2.  2.  2.  3.  3.  3.  4.  5.  5.  5.
>   5.  5.]
>
> Does anybody know whether this code can be made faster, or whether a
> numpy/scipy function exists that establishes this in one go?
>
> thanks
>
> Nicky
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL:
> http://mail.scipy.org/pipermail/scipy-user/attachments/20140204/f6ea1383/attachment-0001.html
>
> ------------------------------
>
> Message: 2
> Date: Tue, 4 Feb 2014 14:52:44 -0500
> From: Warren Weckesser <warren.weckesser at gmail.com>
> Subject: Re: [SciPy-User] "inverting" an array
> To: SciPy Users List <scipy-user at scipy.org>
> Message-ID:
>         <
> CAGzF1uctEZoUCoYQwzveVBhEzGBEeOsvwix4yMO8DDY68D0tGg at mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
>
> On Tue, Feb 4, 2014 at 2:33 PM, nicky van foreest <vanforeest at gmail.com
> >wrote:
>
> > Hi,
> >
> > I am wondering whether a shortcut exists in numpy/scipy for the following
> > problem.  The values in an array represent the number of customers that
> > arrive in a certain time slot, e.g.,
> >
> > a = [0,4,7,3,1,5, 0,0,0,]
> >
> > means that in time slot 1 4 customers arrive, in time slot 2 seven
> arrive,
> > and so on. Now I want to "invert" this array to compute the arrival time
> of
> > the i-th customer. Thus, customer 2 arrives in time slot 1, customer 6 in
> > time slot 2, and so on. For this problem I wrote the following function:
> >
> > a = [0,4,7,3,1,5, 0,0,0,]
> > A = np.cumsum(a)
> >
> > def invert(A):
> >     Ainv = np.empty(A[-1])
> >     aprev=0
> >     for i, a in enumerate(A):
> >         Ainv[aprev:a] = i
> >         aprev = a
> >     return Ainv
> >
> >
> > Ainv= invert(A)
> >
> > print a
> > print A
> > print Ainv
> >
> > The output is
> >
> > [0, 4, 7, 3, 1, 5, 0, 0, 0]
> > [ 0  4 11 14 15 20 20 20 20]
> > [ 1.  1.  1.  1.  2.  2.  2.  2.  2.  2.  2.  3.  3.  3.  4.  5.  5.  5.
> >   5.  5.]
> >
> > Does anybody know whether this code can be made faster, or whether a
> > numpy/scipy function exists that establishes this in one go?
> >
> > thanks
> >
> > Nicky
> >
> >
> You can use `np.repeat`:
>
> In [10]: a
> Out[10]: [0, 4, 7, 3, 1, 5, 0, 0, 0]
>
> In [11]: np.repeat(np.arange(len(a)), a)
> Out[11]: array([1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5,
> 5])
>
>
> Warren
>
>
>
>
> >
> >
> >
> > _______________________________________________
> > SciPy-User mailing list
> > SciPy-User at scipy.org
> > http://mail.scipy.org/mailman/listinfo/scipy-user
> >
> >
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL:
> http://mail.scipy.org/pipermail/scipy-user/attachments/20140204/1b74e682/attachment-0001.html
>
> ------------------------------
>
> Message: 3
> Date: Tue, 04 Feb 2014 13:54:44 -0600
> From: Eric Hermes <ehermes at chem.wisc.edu>
> Subject: Re: [SciPy-User] "inverting" an array
> To: scipy-user at scipy.org
> Message-ID: <52F14584.6090704 at chem.wisc.edu>
> Content-Type: text/plain; charset="iso-8859-1"
>
>
> On 2/4/2014 1:52 PM, Warren Weckesser wrote:
> >
> > On Tue, Feb 4, 2014 at 2:33 PM, nicky van foreest
> > <vanforeest at gmail.com <mailto:vanforeest at gmail.com>> wrote:
> >
> >     Hi,
> >
> >     I am wondering whether a shortcut exists in numpy/scipy for the
> >     following problem.  The values in an array represent the number of
> >     customers that arrive in a certain time slot, e.g.,
> >
> >     a = [0,4,7,3,1,5, 0,0,0,]
> >
> >     means that in time slot 1 4 customers arrive, in time slot 2 seven
> >     arrive, and so on. Now I want to "invert" this array to compute
> >     the arrival time of the i-th customer. Thus, customer 2 arrives in
> >     time slot 1, customer 6 in time slot 2, and so on. For this
> >     problem I wrote the following function:
> >
> >     a = [0,4,7,3,1,5, 0,0,0,]
> >     A = np.cumsum(a)
> >
> >     def invert(A):
> >         Ainv = np.empty(A[-1])
> >         aprev=0
> >         for i, a in enumerate(A):
> >             Ainv[aprev:a] = i
> >             aprev = a
> >         return Ainv
> >
> >
> >     Ainv= invert(A)
> >
> >     print a
> >     print A
> >     print Ainv
> >
> >     The output is
> >
> >     [0, 4, 7, 3, 1, 5, 0, 0, 0]
> >     [ 0  4 11 14 15 20 20 20 20]
> >     [ 1.  1.  1.  1.  2.  2.  2.  2.  2.  2.  2.  3.  3.  3.  4.  5.
> >      5.  5.
> >       5.  5.]
> >
> >     Does anybody know whether this code can be made faster, or whether
> >     a numpy/scipy function exists that establishes this in one go?
> >
> >     thanks
> >
> >     Nicky
> >
> >
> > You can use `np.repeat`:
> > In [10]: a
> > Out[10]: [0, 4, 7, 3, 1, 5, 0, 0, 0]
> >
> > In [11]: np.repeat(np.arange(len(a)), a)
> > Out[11]: array([1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5,
> > 5, 5])
> >
> >
> > Warren
> >
> I came up with a version that only uses python intrinsics:
>
> def invert(a):
>      ainv = []
>      for i, n in enumerate(a):
>          ainv += [i]*n
>      return ainv
>
> Eric
> >
> >
> >
> >
> >     _______________________________________________
> >     SciPy-User mailing list
> >     SciPy-User at scipy.org <mailto:SciPy-User at scipy.org>
> >     http://mail.scipy.org/mailman/listinfo/scipy-user
> >
> >
> >
> >
> > _______________________________________________
> > SciPy-User mailing list
> > SciPy-User at scipy.org
> > http://mail.scipy.org/mailman/listinfo/scipy-user
>
> --
> Eric Hermes
> J.R. Schmidt Group
> Chemistry Department
> University of Wisconsin - Madison
>
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL:
> http://mail.scipy.org/pipermail/scipy-user/attachments/20140204/eba58b20/attachment-0001.html
>
> ------------------------------
>
> Message: 4
> Date: Tue, 4 Feb 2014 21:21:28 +0100
> From: nicky van foreest <vanforeest at gmail.com>
> Subject: Re: [SciPy-User] "inverting" an array
> To: SciPy Users List <scipy-user at scipy.org>
> Message-ID:
>         <CAK_GA2Ek91=QMnis6wd4k5CM+P9fJ4tmtRuhbhRfYGj0efw=
> NA at mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
>
> HI,
>
> Thanks. What an elegant solutions!
>
> bye
>
> Nicky
>
>
>
> On 4 February 2014 20:54, Eric Hermes <ehermes at chem.wisc.edu> wrote:
>
> >
> > On 2/4/2014 1:52 PM, Warren Weckesser wrote:
> >
> >
> >  On Tue, Feb 4, 2014 at 2:33 PM, nicky van foreest <vanforeest at gmail.com
> >wrote:
> >
> >> Hi,
> >>
> >>  I am wondering whether a shortcut exists in numpy/scipy for the
> >> following problem.  The values in an array represent the number of
> >> customers that arrive in a certain time slot, e.g.,
> >>
> >>  a = [0,4,7,3,1,5, 0,0,0,]
> >>
> >>  means that in time slot 1 4 customers arrive, in time slot 2 seven
> >> arrive, and so on. Now I want to "invert" this array to compute the
> arrival
> >> time of the i-th customer. Thus, customer 2 arrives in time slot 1,
> >> customer 6 in time slot 2, and so on. For this problem I wrote the
> >> following function:
> >>
> >>  a = [0,4,7,3,1,5, 0,0,0,]
> >> A = np.cumsum(a)
> >>
> >>  def invert(A):
> >>     Ainv = np.empty(A[-1])
> >>     aprev=0
> >>     for i, a in enumerate(A):
> >>         Ainv[aprev:a] = i
> >>         aprev = a
> >>     return Ainv
> >>
> >>
> >>  Ainv= invert(A)
> >>
> >>  print a
> >> print A
> >> print Ainv
> >>
> >>  The output is
> >>
> >>  [0, 4, 7, 3, 1, 5, 0, 0, 0]
> >> [ 0  4 11 14 15 20 20 20 20]
> >> [ 1.  1.  1.  1.  2.  2.  2.  2.  2.  2.  2.  3.  3.  3.  4.  5.  5.  5.
> >>   5.  5.]
> >>
> >>  Does anybody know whether this code can be made faster, or whether a
> >> numpy/scipy function exists that establishes this in one go?
> >>
> >>  thanks
> >>
> >>  Nicky
> >>
> >>
> >  You can use `np.repeat`:
> >
> > In [10]: a
> > Out[10]: [0, 4, 7, 3, 1, 5, 0, 0, 0]
> >
> > In [11]: np.repeat(np.arange(len(a)), a)
> > Out[11]: array([1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5,
> > 5])
> >
> >
> >  Warren
> >
> >    I came up with a version that only uses python intrinsics:
> >
> > def invert(a):
> >     ainv = []
> >     for i, n in enumerate(a):
> >         ainv += [i]*n
> >     return ainv
> >
> > Eric
> >
> >
> >
> >
> >>
> >>
> >>
> >> _______________________________________________
> >> SciPy-User mailing list
> >> SciPy-User at scipy.org
> >> http://mail.scipy.org/mailman/listinfo/scipy-user
> >>
> >>
> >
> >
> > _______________________________________________
> > SciPy-User mailing listSciPy-User at scipy.orghttp://
> mail.scipy.org/mailman/listinfo/scipy-user
> >
> >
> > --
> > Eric Hermes
> > J.R. Schmidt Group
> > Chemistry Department
> > University of Wisconsin - Madison
> >
> >
> > _______________________________________________
> > SciPy-User mailing list
> > SciPy-User at scipy.org
> > http://mail.scipy.org/mailman/listinfo/scipy-user
> >
> >
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL:
> http://mail.scipy.org/pipermail/scipy-user/attachments/20140204/4e90e967/attachment.html
>
> ------------------------------
>
> _______________________________________________
> SciPy-User mailing list
> SciPy-User at scipy.org
> http://mail.scipy.org/mailman/listinfo/scipy-user
>
>
> End of SciPy-User Digest, Vol 126, Issue 5
> ******************************************
>



-- 
Justus Schwabedal

skype: justus1802
Work: +1 617 353 4659
Handy (US): +1 617 449 8478
Handy (D): +49 177 939 5281
email: jschwabedal at googlemail.com

657 John Wesley Dobbs Ave NE
30312 Atlanta, GA
USA

Steinkreuzstr. 23
53757 Sankt Augustin
Germany
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.scipy.org/pipermail/scipy-user/attachments/20140204/a9ac03ee/attachment.html>


More information about the SciPy-User mailing list