From 1d3bcb446771ff16e9cf06e3a5d9cac20e68c4ac Mon Sep 17 00:00:00 2001 From: jaimefrio Date: Tue, 20 Jan 2015 19:15:00 -0800 Subject: [PATCH] ENH: Make swapaxes always return a view swapaxes now returns a view of the input array when the axes to swap are both the same, not the input array as it used to do. Fixes #5260 --- doc/release/1.10.0-notes.rst | 9 +++++-- numpy/core/fromnumeric.py | 6 +++-- numpy/core/src/multiarray/shape.c | 40 ++++++++++--------------------- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/doc/release/1.10.0-notes.rst b/doc/release/1.10.0-notes.rst index 26559ad32c31..76538760eea5 100644 --- a/doc/release/1.10.0-notes.rst +++ b/doc/release/1.10.0-notes.rst @@ -50,12 +50,17 @@ the case of matrices. Matrices are special cased for backward compatibility and still return 1-D arrays as before. If you need to preserve the matrix subtype, use the methods instead of the functions. -*rollaxis* always returns a view -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*rollaxis* and *swapaxes* always return a view +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Previously, a view was returned except when no change was made in the order of the axes, in which case the input array was returned. A view is now returned in all cases. +C API +~~~~~ +The changes to *swapaxes* also apply to the *PyArray_SwapAxes* C function, +which now returns a view in all cases. + New Features ============ diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 2a527a4a483b..aef09411ab69 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -464,8 +464,10 @@ def swapaxes(a, axis1, axis2): Returns ------- a_swapped : ndarray - If `a` is an ndarray, then a view of `a` is returned; otherwise - a new array is created. + For Numpy >= 1.10, if `a` is an ndarray, then a view of `a` is + returned; otherwise a new array is created. For earlier Numpy + versions a view of `a` is returned only if the order of the + axes is changed, otherwise the input array is returned. Examples -------- diff --git a/numpy/core/src/multiarray/shape.c b/numpy/core/src/multiarray/shape.c index df1874594558..f1e81ff6b5f9 100644 --- a/numpy/core/src/multiarray/shape.c +++ b/numpy/core/src/multiarray/shape.c @@ -653,19 +653,8 @@ PyArray_SwapAxes(PyArrayObject *ap, int a1, int a2) { PyArray_Dims new_axes; npy_intp dims[NPY_MAXDIMS]; - int n, i, val; - PyObject *ret; - - if (a1 == a2) { - Py_INCREF(ap); - return (PyObject *)ap; - } - - n = PyArray_NDIM(ap); - if (n <= 1) { - Py_INCREF(ap); - return (PyObject *)ap; - } + int n = PyArray_NDIM(ap); + int i; if (a1 < 0) { a1 += n; @@ -683,25 +672,20 @@ PyArray_SwapAxes(PyArrayObject *ap, int a1, int a2) "bad axis2 argument to swapaxes"); return NULL; } + + for (i = 0; i < n; ++i) { + dims[i] = i; + } + dims[a1] = a2; + dims[a2] = a1; + new_axes.ptr = dims; new_axes.len = n; - for (i = 0; i < n; i++) { - if (i == a1) { - val = a2; - } - else if (i == a2) { - val = a1; - } - else { - val = i; - } - new_axes.ptr[i] = val; - } - ret = PyArray_Transpose(ap, &new_axes); - return ret; + return PyArray_Transpose(ap, &new_axes); } + /*NUMPY_API * Return Transpose. */ @@ -969,7 +953,7 @@ PyArray_Ravel(PyArrayObject *arr, NPY_ORDER order) PyArray_CreateSortedStridePerm(PyArray_NDIM(arr), PyArray_STRIDES(arr), strideperm); - + for (i = ndim-1; i >= 0; --i) { if (PyArray_DIM(arr, strideperm[i].perm) == 1) { /* A size one dimension does not matter */