Repository: pandas-dev/pandas

Issue:
BUG: Index.get_indexer_not_unique inconsistent return types vs get_indexer
See https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Index.get_indexer_non_unique.html where the return value of Index.get_indexer_non_unique indexer is stated to be ndarray whereas actually this is converted into a Index before it is returned 

indexer, missing = self._engine.get_indexer_non_unique(tgt_values)
return Index(indexer), missing





Discussion:

Resolving patch:
diff --git a/pandas/core/groupby.py b/pandas/core/groupby.py
--- a/pandas/core/groupby.py
+++ b/pandas/core/groupby.py
@@ -896,8 +896,9 @@ def reset_identity(values):
                 # we can't reindex, so we resort to this
                 # GH 14776
                 if isinstance(ax, MultiIndex) and not ax.is_unique:
-                    result = result.take(result.index.get_indexer_for(
-                        ax.values).unique(), axis=self.axis)
+                    indexer = algorithms.unique1d(
+                        result.index.get_indexer_for(ax.values))
+                    result = result.take(indexer, axis=self.axis)
                 else:
                     result = result.reindex_axis(ax, axis=self.axis)
 
diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py
--- a/pandas/core/indexes/base.py
+++ b/pandas/core/indexes/base.py
@@ -2256,8 +2256,8 @@ def intersection(self, other):
             indexer = indexer.take((indexer != -1).nonzero()[0])
         except:
             # duplicates
-            indexer = Index(other._values).get_indexer_non_unique(
-                self._values)[0].unique()
+            indexer = algos.unique1d(
+                Index(other._values).get_indexer_non_unique(self._values)[0])
             indexer = indexer[indexer != -1]
 
         taken = other.take(indexer)
@@ -2704,7 +2704,7 @@ def get_indexer_non_unique(self, target):
             tgt_values = target._values
 
         indexer, missing = self._engine.get_indexer_non_unique(tgt_values)
-        return Index(indexer), missing
+        return indexer, missing
 
     def get_indexer_for(self, target, **kwargs):
         """
@@ -2942,7 +2942,6 @@ def _reindex_non_unique(self, target):
             else:
 
                 # need to retake to have the same size as the indexer
-                indexer = indexer.values
                 indexer[~check] = 0
 
                 # reset the new indexer to account for the new size


Test patch:
diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py
--- a/pandas/tests/indexes/test_base.py
+++ b/pandas/tests/indexes/test_base.py
@@ -1131,6 +1131,17 @@ def test_get_indexer_strings(self):
         with pytest.raises(TypeError):
             idx.get_indexer(['a', 'b', 'c', 'd'], method='pad', tolerance=2)
 
+    def test_get_indexer_consistency(self):
+        # See GH 16819
+        for name, index in self.indices.items():
+            indexer = index.get_indexer(index[0:2])
+            assert isinstance(indexer, np.ndarray)
+            assert indexer.dtype == np.intp
+
+            indexer, _ = index.get_indexer_non_unique(index[0:2])
+            assert isinstance(indexer, np.ndarray)
+            assert indexer.dtype == np.intp
+
     def test_get_loc(self):
         idx = pd.Index([0, 1, 2])
         all_methods = [None, 'pad', 'backfill', 'nearest']
diff --git a/pandas/tests/indexes/test_category.py b/pandas/tests/indexes/test_category.py
--- a/pandas/tests/indexes/test_category.py
+++ b/pandas/tests/indexes/test_category.py
@@ -386,8 +386,7 @@ def test_reindexing(self):
             expected = oidx.get_indexer_non_unique(finder)[0]
 
             actual = ci.get_indexer(finder)
-            tm.assert_numpy_array_equal(
-                expected.values, actual, check_dtype=False)
+            tm.assert_numpy_array_equal(expected, actual)
 
     def test_reindex_dtype(self):
         c = CategoricalIndex(['a', 'b', 'c', 'a'])