Repository: pandas-dev/pandas
Pull request: Deprecated Index.get_duplicates()
- [X] closes #20239
- [X] tests added / passed
- [X] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [X] whatsnew entry


Problem statement:
DEPR: Index.get_duplicates
completely duplicates (pun-intended) .duplicated / .drop_duplicates and is unecessary.

```
In [1]: pd.Index([1, 2, 3, 2, 3, 4, 3]).get_duplicates()
Out[1]: [2, 3]

In [2]: pd.Index([1, 2, 3, 2, 3, 4, 3]).drop_duplicates()
Out[2]: Int64Index([1, 2, 3, 4], dtype='int64')

In [3]: pd.Index([1, 2, 3, 2, 3, 4, 3]).duplicated()
Out[3]: array([False, False, False,  True,  True, False,  True])

In [4]: i = pd.Index([1, 2, 3, 2, 3, 4, 3])

In [5]: i[i.duplicated()]
Out[5]: Int64Index([2, 3, 3], dtype='int64')

In [6]: i[i.duplicated()].unique()
Out[6]: Int64Index([2, 3], dtype='int64')
```

Hints from issue discussion:

Commit message: Deprecated Index.get_duplicates()

Patch to review:
diff --git a/doc/source/whatsnew/v0.23.0.txt b/doc/source/whatsnew/v0.23.0.txt
index e83f149db1f18..cb3544b5df3a6 100644
--- a/doc/source/whatsnew/v0.23.0.txt
+++ b/doc/source/whatsnew/v0.23.0.txt
@@ -831,6 +831,7 @@ Deprecations
 - ``pandas.tseries.plotting.tsplot`` is deprecated. Use :func:`Series.plot` instead (:issue:`18627`)
 - ``Index.summary()`` is deprecated and will be removed in a future version (:issue:`18217`)
 - ``NDFrame.get_ftype_counts()`` is deprecated and will be removed in a future version (:issue:`18243`)
+- ``Index.get_duplicates()`` is deprecated and will be removed in a future version (:issue:`20239`)
 
 .. _whatsnew_0230.prior_deprecations:
 
diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py
index 12bb09e8f8a8a..51b3b682fd4a5 100644
--- a/pandas/core/indexes/base.py
+++ b/pandas/core/indexes/base.py
@@ -1824,6 +1824,9 @@ def get_duplicates(self):
         Returns a sorted list of index elements which appear more than once in
         the index.
 
+        .. deprecated:: 0.23.0
+            Use idx[idx.duplicated()].unique() instead
+
         Returns
         -------
         array-like
@@ -1870,14 +1873,20 @@ def get_duplicates(self):
         >>> pd.Index(dates).get_duplicates()
         DatetimeIndex([], dtype='datetime64[ns]', freq=None)
         """
+        warnings.warn("'get_duplicates' is deprecated and will be removed in "
+                      "a future release. You can use "
+                      "idx[idx.duplicated()].unique() instead",
+                      FutureWarning, stacklevel=2)
+
+        return self._get_duplicates()
+
+    def _get_duplicates(self):
         from collections import defaultdict
         counter = defaultdict(lambda: 0)
         for k in self.values:
             counter[k] += 1
         return sorted(k for k, v in compat.iteritems(counter) if v > 1)
 
-    _get_duplicates = get_duplicates
-
     def _cleanup(self):
         self._engine.clear_mapping()
 
diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py
index ff9c86fbfe384..d396d3b7e0036 100644
--- a/pandas/tests/indexes/test_base.py
+++ b/pandas/tests/indexes/test_base.py
@@ -2061,6 +2061,11 @@ def test_cached_properties_not_settable(self):
         with tm.assert_raises_regex(AttributeError, "Can't set attribute"):
             idx.is_unique = False
 
+    def test_get_duplicates_deprecated(self):
+        idx = pd.Index([1, 2, 3])
+        with tm.assert_produces_warning(FutureWarning):
+            idx.get_duplicates()
+
 
 class TestMixedIntIndex(Base):
     # Mostly the tests from common.py for which the results differ


Code review comments:
diff_hunk: @@ -1870,14 +1873,20 @@ def get_duplicates(self):
         >>> pd.Index(dates).get_duplicates()
         DatetimeIndex([], dtype='datetime64[ns]', freq=None)
         """
+        warnings.warn("'get_duplicates' is deprecated and will be removed in "
+                      "a future release. You can use "
+                      "idx[idx.duplicated()].unique() instead",
+                      FutureWarning, stacklevel=2)
+
+        return self._get_duplicates()
+
+    def _get_duplicates(self):
path: pandas/core/indexes/base.py
text: @user1:
would rather change the impl itself here as well to the suggested one