# [Numpy-discussion] Re: Method to shift elements in an array?

Alan G Isaac aisaac at american.edu
Fri Feb 24 21:44:02 CST 2006

```Tim wrote:
> import numpy
> def roll(A, n):
>     "Roll the array A in place. Positive n -> roll right, negative n ->
> roll left"
>     if n > 0:
>         n = abs(n)
>         temp = A[-n:]
>         A[n:] = A[:-n]
>         A[:n] = temp
>     elif n < 0:
>         n = abs(n)
>         temp = A[:n]
>         A[:-n] = A[n:]
>         A[-n:] = temp
>     else:
>         pass

This probably counts as a gotcha:
>>> a=N.arange(10)
>>> temp=a[-6:]
>>> a[6:]=a[:-6]
>>> a[:6]=temp
>>> a
array([4, 5, 0, 1, 2, 3, 0, 1, 2, 3])

Cheers,
Alan Isaac

PS Here's something close to the rotater functionality.

#rotater: rotate row elements
# Format:    y = rotater(x,r,copydata)
# Input:     x           RxC array
#            rotateby    size R integer array, or integer (rotation amounts)
#            inplace     boolean (default is False -> copies data)
# Output:    y           RxC array:
#                          rows rotated by rotateby
#                        or None (if inplace=True)
# Remarks:   Intended for use with 2D arrays.
#            rotateby values are positive for rightward rotation,
#	               negative for leftward rotation
# :author: Alan G Isaac (aisaac AT american DOT edu)
# :date:   24 Feb 2006
def rotater(x,rotateby,inplace=False) :
assert(len(x.shape)==2), "For 2-d arrays only."
xrotate = numpy.array(x,copy=(not inplace))
xrows = xrotate.shape[0]
#make an iterater of row shifts
if isinstance(rotateby,int):
from itertools import repeat
rowshifts = repeat(rotateby,xrows)
else:
rowshifts = numpy.asarray(rotateby)
assert(rowshifts.size==xrows)
rowshifts = rowshifts.flat
#perform rotation on each row
for row in xrange(xrows):
rs=rowshifts.next()
#do nothing if rs==0
if rs>0:
xrotate[row] = numpy.concatenate([xrotate[row][-rs:],xrotate[row][:-rs]])
elif rs<0:
xrotate[row] = numpy.concatenate([xrotate[row][:-rs],xrotate[row][-rs:]])
if inplace:
return None
else:
return xrotate

```