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

Thomas Coffee thomasmcoffee@gmail....
Fri Feb 15 20:59:08 CST 2013


Adding to an old discussion thread (see below) ... an implementation
of the proposed functionality:

from numpy import rollaxis
def moveaxis(a, i, j = 0):
    """
    move axis i of array a to position j
    """
    n = a.ndim
    i = i if i >= 0 else i + n
    if j > i:
        return rollaxis(a, i, j + 1)
    elif j >= 0:
        return rollaxis(a, i, j)
    elif j == -1:
        return rollaxis(a, i, n)
    elif j >= -i:
        return rollaxis(a, i, j + 1)
    else:
        return rollaxis(a, i, j)


Examples:


In [464]: a = numpy.ones((3,4,5,6))

In [465]: moveaxis(a,2,0).shape
Out[465]: (5, 3, 4, 6)

In [466]: moveaxis(a,2,1).shape
Out[466]: (3, 5, 4, 6)

In [467]: moveaxis(a,2,2).shape
Out[467]: (3, 4, 5, 6)

In [468]: moveaxis(a,2,3).shape
Out[468]: (3, 4, 6, 5)

In [469]: moveaxis(a,2,4).shape
---------------------------------------------------------------------------
ValueError: rollaxis: start (5) must be >=0 and < 5

In [470]: moveaxis(a,2,-1).shape
Out[470]: (3, 4, 6, 5)

In [471]: moveaxis(a,2,-2).shape
Out[471]: (3, 4, 5, 6)

In [472]: moveaxis(a,2,-3).shape
Out[472]: (3, 5, 4, 6)

In [473]: moveaxis(a,2,-4).shape
Out[473]: (5, 3, 4, 6)

In [474]: moveaxis(a,2,-5).shape
---------------------------------------------------------------------------
ValueError: rollaxis: start (-1) must be >=0 and < 5



On Thu, Sep 23, 2010 at 11:33 AM, Nathaniel Smith wrote:
>
> On Tue, Sep 21, 2010 at 12:48 PM, Ken Basye <kbasye1@jhu.edu> wrote:
> > If that's going to break too much code, here's a pathway that might be
> > acceptable:  Add a new function moveaxis() which works the way
> > rollaxis() does for positive arguments but in the new way for negative
> > arguments.  Eventually, rollaxis could be deprecated to keep things
> > tidy.  This has the added advantage of using a name that seems to fit
> > what the function does better - 'rollaxis' suggests a behavior like the
> > roll() function which affects other axes, which isn't what happens.
>
> My 2 cents: +1 on a new function, but I'd change the behavior for
> positive arguments too.
>
> Currently, the API is (AFAICT): You give the index of the axis you
> want to move, and you give the index of the axis that you want the
> first axis to be moved in front of. This is super confusing!
>
> I propose that a much better API would be: You give the index of the
> axis you want to move, and you give the index you *want* that axis to
> have.  So we'd have the invariant:
>   b = np.moveaxis(a, i, j)
>   assert a.shape[i] == b.shape[j]
> This is way easier to think about, at least for me. And it solves the
> problem with negative indices too.
>
> BTW, note that that the documentation for rollaxis is actually
> self-contradictory at the moment:
>    http://docs.scipy.org/doc/numpy/reference/generated/numpy.rollaxis.html
> At the top it seems to document the behavior that I propose ("Roll the
> specified axis backwards, until it lies *in a given* position."), and
> then in the details it describes the actual behavior("The axis is
> rolled until it lies *before* this position"). I take this as further
> evidence that the current behavior is unnatural and confusing :-).
>
> -- Nathaniel


More information about the NumPy-Discussion mailing list