Repository: numpy/numpy

Issue:
np.delete changes order to C
Hello,

there is probably a bug on np.delete as it changes data order from fortran to C in the following case:

```
In [1]: import numpy as np

In [2]: k=np.arange(10).reshape(2,5,order='F')

In [6]: m=np.delete(k,slice(60,None),axis=1)

In [7]: m.flags
Out[7]: 
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False

In [24]: np.__version__
Out[24]: '1.10.1'
```

That is, when you call it and it does not delete any index. What's funny, though, is that it keeps data representation the same. Other cases seem to maintain data order.

Thanks,
Werner.



Discussion:
It seems the empty slice is an explicit special case, which is fine, but it does not have the `arrorder` logic the other code paths have:

```
        new = empty(newshape, arr.dtype, arrorder)
```

The empty slice code path should probably use `arrorder` for the copy, since all the others seem to do it. If you have some time to have a look, this is some pure python code in numpy/lib/function_base.py, it would be much appreciated.

Hi, I am not sure whether this is the reason, but looks like [this](https://github.com/numpy/numpy/blob/master/numpy/lib/function_base.py#L4005) call of `ndarray.copy` is the reason for the change of the order

```
>>> k.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
>>>np.copy(k).flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
>>>k.copy().flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
```

It seems that the documentation of the `ndarray.copy` mentions the change of order to C
Hope it helps. Please let me know if I am missing something. Cheers.


Resolving patch:
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -4097,7 +4097,7 @@ def delete(arr, obj, axis=None):
         if wrap:
             return wrap(arr)
         else:
-            return arr.copy()
+            return arr.copy(order=arrorder)
 
     slobj = [slice(None)]*ndim
     N = arr.shape[axis]
@@ -4110,9 +4110,9 @@ def delete(arr, obj, axis=None):
 
         if numtodel <= 0:
             if wrap:
-                return wrap(arr.copy())
+                return wrap(arr.copy(order=arrorder))
             else:
-                return arr.copy()
+                return arr.copy(order=arrorder)
 
         # Invert if step is negative:
         if step < 0:
@@ -4333,7 +4333,7 @@ def insert(arr, obj, values, axis=None):
         warnings.warn(
             "in the future the special handling of scalars will be removed "
             "from insert and raise an error", DeprecationWarning)
-        arr = arr.copy()
+        arr = arr.copy(order=arrorder)
         arr[...] = values
         if wrap:
             return wrap(arr)


Test patch:
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py
--- a/numpy/lib/tests/test_function_base.py
+++ b/numpy/lib/tests/test_function_base.py
@@ -533,6 +533,16 @@ class SubClass(np.ndarray):
         assert_(isinstance(delete(a, slice(1, 2)), SubClass))
         assert_(isinstance(delete(a, slice(1, -2)), SubClass))
 
+    def test_array_order_preserve(self):
+        # See gh-7113
+        k = np.arange(10).reshape(2, 5, order='F')
+        m = delete(k, slice(60, None), axis=1)
+
+        # 'k' is Fortran ordered, and 'm' should have the
+        # same ordering as 'k' and NOT become C ordered
+        assert_equal(m.flags.c_contiguous, k.flags.c_contiguous)
+        assert_equal(m.flags.f_contiguous, k.flags.f_contiguous)
+
 
 class TestGradient(TestCase):