[Numpy-discussion] Shift or rotate command?

Bill Baxter wbaxter at gmail.com
Sun Sep 24 20:44:25 EDT 2006


Howdy Angus,
Yeh, that does seem like a hole in the API.  Travis added a rollaxis()
but there's still no simple way to roll the elements themselves.

I took a look at numpy.fft.fftshift, which is a function that has to
do a similar thing.  It does it by concatenating aranges and then
doing a take().  Presumably Pearu knew what he was doing when he wrote
that, so we can assume this is probably close to the best possible.
:-)  From that idea here's a function that implements roll().

def roll(y,shift,axis):
    """Roll the elements in the array by 'shift' positions along the
given axis."""
    from numpy import asanyarray,concatenate,arange
    y = asanyarray(y)
    n = y.shape[axis]
    shift %= n # does the right thing for negative shifts, too
    return y.take(concatenate((arange(shift,n),arange(shift))), axis)

Performance is only very slightly worse (<1%) using
    return y.take(r_[shift:n, :shift], axis)
as the last line, which is maybe slightly more readable if you're down
wit' the r_.

I prefer the name 'roll' because:
a) there's already rollaxis with conceptually similar behavior and
b) 'shift' is used in other languages (perl comes to mind) sometimes
to indicate shifting off the end, possibly filling in with zeros or
just leaving the array shorter.
c) 'rotate' seems potentially confusing given the existence of the
'rot90' function already.

--bb


On 9/25/06, Angus McMorland <amcmorl at gmail.com> wrote:
> Hi all,
>
> Other data languages that I have worked with have a routine for shifting
> data along axes, with wrapping.
> In IDL it's called 'shift', and works such that
> print, a
> 0 1 2 3
> 4 5 6 7
> 8 9 10 11
>
> print, shift(a, 2, 0)
> 2 3 0 1
> 6 7 4 5
> 10 11 8 9
>
> print, shift(a, 2, 1)
> 10 11 8 9
> 2 3 0 1
> 6 7 4 5
>
> In pdl (pdl.perl.org) the equivalent routine is called rotate. Is there a
> version of this in numpy, or can it be easily achieved using existing
> technology - I could do it with multiple sliced assignment statements but
> that seems very clunky and likely slow. I've looked through the examples and
> the numpy book but without success.
>
> Angus.




More information about the NumPy-Discussion mailing list