Repository: numpy/numpy

Issue:
Use of `ravel` in `intersect1d` breaks compatibility with xarray
See https://github.com/pydata/xarray/issues/2371

### Numpy/Python version information:

```
1.15.0 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 17:14:51) 
[GCC 7.2.0]
```




Discussion:
The other issue sounds like this is a regression. `reshape(-1)` might be a nicer way to achieve the same thing anyway, not sure what changed though.
Arrived with #10684.
As another datapoint, `unique` ends up calling `.flatten()`, I guess since in most cases it needs the copy anyway to do an in-place sort.

Resolving patch:
diff --git a/numpy/lib/arraysetops.py b/numpy/lib/arraysetops.py
--- a/numpy/lib/arraysetops.py
+++ b/numpy/lib/arraysetops.py
@@ -312,12 +312,12 @@ def intersect1d(ar1, ar2, assume_unique=False, return_indices=False):
         If True, the input arrays are both assumed to be unique, which
         can speed up the calculation.  Default is False.
     return_indices : bool
-        If True, the indices which correspond to the intersection of the 
-        two arrays are returned. The first instance of a value is used 
-        if there are multiple. Default is False. 
-    
-        .. versionadded:: 1.15.0    
-        
+        If True, the indices which correspond to the intersection of the two
+        arrays are returned. The first instance of a value is used if there are
+        multiple. Default is False.
+
+        .. versionadded:: 1.15.0
+
     Returns
     -------
     intersect1d : ndarray
@@ -326,7 +326,7 @@ def intersect1d(ar1, ar2, assume_unique=False, return_indices=False):
         The indices of the first occurrences of the common values in `ar1`.
         Only provided if `return_indices` is True.
     comm2 : ndarray
-        The indices of the first occurrences of the common values in `ar2`. 
+        The indices of the first occurrences of the common values in `ar2`.
         Only provided if `return_indices` is True.
 
 
@@ -345,7 +345,7 @@ def intersect1d(ar1, ar2, assume_unique=False, return_indices=False):
     >>> from functools import reduce
     >>> reduce(np.intersect1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))
     array([3])
-    
+
     To return the indices of the values common to the input arrays
     along with the intersected values:
     >>> x = np.array([1, 1, 2, 3, 4])
@@ -355,8 +355,11 @@ def intersect1d(ar1, ar2, assume_unique=False, return_indices=False):
     (array([0, 2, 4]), array([1, 0, 2]))
     >>> xy, x[x_ind], y[y_ind]
     (array([1, 2, 4]), array([1, 2, 4]), array([1, 2, 4]))
-    
+
     """
+    ar1 = np.asanyarray(ar1)
+    ar2 = np.asanyarray(ar2)
+
     if not assume_unique:
         if return_indices:
             ar1, ind1 = unique(ar1, return_index=True)
@@ -367,7 +370,7 @@ def intersect1d(ar1, ar2, assume_unique=False, return_indices=False):
     else:
         ar1 = ar1.ravel()
         ar2 = ar2.ravel()
-        
+
     aux = np.concatenate((ar1, ar2))
     if return_indices:
         aux_sort_indices = np.argsort(aux, kind='mergesort')
@@ -389,6 +392,7 @@ def intersect1d(ar1, ar2, assume_unique=False, return_indices=False):
     else:
         return int1d
 
+
 def setxor1d(ar1, ar2, assume_unique=False):
     """
     Find the set exclusive-or of two arrays.


Test patch:
diff --git a/numpy/lib/tests/test_arraysetops.py b/numpy/lib/tests/test_arraysetops.py
--- a/numpy/lib/tests/test_arraysetops.py
+++ b/numpy/lib/tests/test_arraysetops.py
@@ -30,19 +30,30 @@ def test_intersect1d(self):
         ed = np.array([1, 2, 5])
         c = intersect1d(a, b)
         assert_array_equal(c, ed)
-
         assert_array_equal([], intersect1d([], []))
-        
+
+    def test_intersect1d_array_like(self):
+        # See gh-11772
+        class Test(object):
+            def __array__(self):
+                return np.arange(3)
+
+        a = Test()
+        res = intersect1d(a, a)
+        assert_array_equal(res, a)
+        res = intersect1d([1, 2, 3], [1, 2, 3])
+        assert_array_equal(res, [1, 2, 3])
+
     def test_intersect1d_indices(self):
         # unique inputs
-        a = np.array([1, 2, 3, 4]) 
+        a = np.array([1, 2, 3, 4])
         b = np.array([2, 1, 4, 6])
         c, i1, i2 = intersect1d(a, b, assume_unique=True, return_indices=True)
         ee = np.array([1, 2, 4])
         assert_array_equal(c, ee)
         assert_array_equal(a[i1], ee)
         assert_array_equal(b[i2], ee)
-        
+
         # non-unique inputs
         a = np.array([1, 2, 2, 3, 4, 3, 2])
         b = np.array([1, 8, 4, 2, 2, 3, 2, 3])
@@ -51,7 +62,7 @@ def test_intersect1d_indices(self):
         assert_array_equal(c, ef)
         assert_array_equal(a[i1], ef)
         assert_array_equal(b[i2], ef)
-                
+
         # non1d, unique inputs
         a = np.array([[2, 4, 5, 6], [7, 8, 1, 15]])
         b = np.array([[3, 2, 7, 6], [10, 12, 8, 9]])
@@ -61,7 +72,7 @@ def test_intersect1d_indices(self):
         ea = np.array([2, 6, 7, 8])
         assert_array_equal(ea, a[ui1])
         assert_array_equal(ea, b[ui2])
-    
+
         # non1d, not assumed to be uniqueinputs
         a = np.array([[2, 4, 5, 6, 6], [4, 7, 8, 7, 2]])
         b = np.array([[3, 2, 7, 7], [10, 12, 8, 7]])
@@ -71,7 +82,7 @@ def test_intersect1d_indices(self):
         ea = np.array([2, 7, 8])
         assert_array_equal(ea, a[ui1])
         assert_array_equal(ea, b[ui2])
-        
+
     def test_setxor1d(self):
         a = np.array([5, 7, 1, 2])
         b = np.array([2, 4, 3, 1, 5])