[Numpy-discussion] A proposed change to rollaxis(), behavior for negative 'start' values

Ken Basye kbasye1@jhu....
Thu Sep 23 09:42:58 CDT 2010

    Anne says:

    This is a tricky one. The current behaviour of rollaxis is to remove
    the requested axis from the list of axes and then insert it before the
    axis specified. This is exactly how python's list insertion works:

    In [1]: a = range(10)

    In [3]: a.insert(-1,'a')

    In [4]: a
    Out[4]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 'a', 9]

    And indeed, there's no clean way to add something to the end of a list
    using insert (apart from the obvious a.insert(len(a),'b') ). For this
    you have .append(). Unfortunately numpy's rollaxis, while it agrees
    with insert in its behaviour, doesn't have a move_axis_to_end. The
    situation is also somewhat muddied by the fact that rollaxis also
    removes the axis from the original list of axes, so that the
    interpretation of index numbers is a little more subtle. But I think
    your suggested behaviour would be confusing because of the conflict
    with python's insert. How about allowing the string "end" as an
    argument to rollaxis to specify that the axis should go at the end?


    Ralf says:

    Allowing "end" is an easy solution, but note that moving an axis to the end
    > is already possible:

>>>     > >>> a = np.ones((3,4,5,6))
>>>     > >>> np.rollaxis(a, 2, len(a)+1).shape  # roll axis to to last position
    > (3, 4, 6, 5)
    > Not consistent with insert though, there you would use len(a) instead of
    > len(a)+1. It's a little ugly, but perhaps just documenting this is no worse
    > than allowing a string or adding yet another function.

    Chuck says:

    It is a common enough operation that it would be nice to have a less
    cumbersome way to specify it.

Ralf, that's not going to work generally, because len(a) is a.shape[0], 
right?  It works in the example above but if I had done

>>> a = np.ones((1,2,3,4))

it wouldn't work.  In my original posting, I suggested 

 >>> np.rollaxis(a, 2, len(a.shape))

which I think will work fine, but it still seems cumbersome, as Chuck 
points out.

I'm going to take one more tilt at the windmill.  To me, the connection with Python's insert() is tenuous: insert() is a destructive operation whereas rollaxis() returns a new array with the requested change, also rollaxis is doing the delete and insert in one step.  I know the implementation uses insert() and delete(), but I think the natural way to think about rollaxis() is in terms of moving an axis from one position to another and there is no Python analog to that.  

Anne's comment that "the situation is somehat muddied..." is precisely why I think the change is worth making - if the meaning of the 'start' argument were changed from "The axis is rolled until it lies before this position." to "The axis is rolled until it lies *at* this position." then it seems to me there's no confusion.  The current description "The axis is rolled until it lies before this position."  is ambiguous because "this position" seems like it means "position in the shape of the array" but then what's the position before 0?  So how about "The axis is rolled until it lies before the axis currently at this position."  That's much closer, but now it's hard to make sense of using len(a.shape) as an argument, since there is no axis currently at len(a.shape).  To really capture the muddiness, we need to say something like "The axis is rolled until it lies before the axis currently at this position, unless the value is len(a.shape), in which case the axis is rolled to the end" - yuck.  

Again, note that the proposed change applies only to positions specified with negative indices; positive indices will all work as before.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.scipy.org/pipermail/numpy-discussion/attachments/20100923/8f085634/attachment.html 

More information about the NumPy-Discussion mailing list