[Numpy-discussion] A proposed change to rollaxis(), behavior for negative 'start' values
Ken Basye
kbasye1 at jhu.edu
Thu Sep 23 10:42:58 EDT 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?
Anne
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.
Best,
Ken
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20100923/8f085634/attachment.html>
More information about the NumPy-Discussion
mailing list