Skip to content

Commit 9e6b50f

Browse files
authored
REF: IndexOpsMixin wrapping (#36848)
1 parent 849b0d0 commit 9e6b50f

File tree

3 files changed

+29
-22
lines changed

3 files changed

+29
-22
lines changed

pandas/core/base.py

+19-20
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import builtins
66
import textwrap
7-
from typing import Any, Callable, Dict, FrozenSet, List, Optional, Union, cast
7+
from typing import Any, Callable, Dict, FrozenSet, List, Optional, TypeVar, Union, cast
88

99
import numpy as np
1010

@@ -43,6 +43,8 @@
4343
duplicated="IndexOpsMixin",
4444
)
4545

46+
_T = TypeVar("_T", bound="IndexOpsMixin")
47+
4648

4749
class PandasObject(DirNamesMixin):
4850
"""
@@ -604,7 +606,7 @@ def _values(self) -> Union[ExtensionArray, np.ndarray]:
604606
# must be defined here as a property for mypy
605607
raise AbstractMethodError(self)
606608

607-
def transpose(self, *args, **kwargs):
609+
def transpose(self: _T, *args, **kwargs) -> _T:
608610
"""
609611
Return the transpose, which is by definition self.
610612
@@ -851,10 +853,10 @@ def to_numpy(self, dtype=None, copy=False, na_value=lib.no_default, **kwargs):
851853
return result
852854

853855
@property
854-
def empty(self):
856+
def empty(self) -> bool:
855857
return not self.size
856858

857-
def max(self, axis=None, skipna=True, *args, **kwargs):
859+
def max(self, axis=None, skipna: bool = True, *args, **kwargs):
858860
"""
859861
Return the maximum value of the Index.
860862
@@ -899,7 +901,7 @@ def max(self, axis=None, skipna=True, *args, **kwargs):
899901
return nanops.nanmax(self._values, skipna=skipna)
900902

901903
@doc(op="max", oppose="min", value="largest")
902-
def argmax(self, axis=None, skipna=True, *args, **kwargs):
904+
def argmax(self, axis=None, skipna: bool = True, *args, **kwargs) -> int:
903905
"""
904906
Return int position of the {value} value in the Series.
905907
@@ -954,7 +956,7 @@ def argmax(self, axis=None, skipna=True, *args, **kwargs):
954956
nv.validate_argmax_with_skipna(skipna, args, kwargs)
955957
return nanops.nanargmax(self._values, skipna=skipna)
956958

957-
def min(self, axis=None, skipna=True, *args, **kwargs):
959+
def min(self, axis=None, skipna: bool = True, *args, **kwargs):
958960
"""
959961
Return the minimum value of the Index.
960962
@@ -999,7 +1001,7 @@ def min(self, axis=None, skipna=True, *args, **kwargs):
9991001
return nanops.nanmin(self._values, skipna=skipna)
10001002

10011003
@doc(argmax, op="min", oppose="max", value="smallest")
1002-
def argmin(self, axis=None, skipna=True, *args, **kwargs):
1004+
def argmin(self, axis=None, skipna=True, *args, **kwargs) -> int:
10031005
nv.validate_minmax_axis(axis)
10041006
nv.validate_argmax_with_skipna(skipna, args, kwargs)
10051007
return nanops.nanargmin(self._values, skipna=skipna)
@@ -1054,6 +1056,9 @@ def hasnans(self):
10541056
"""
10551057
return bool(isna(self).any())
10561058

1059+
def isna(self):
1060+
return isna(self._values)
1061+
10571062
def _reduce(
10581063
self,
10591064
op,
@@ -1161,7 +1166,12 @@ def map_f(values, f):
11611166
return new_values
11621167

11631168
def value_counts(
1164-
self, normalize=False, sort=True, ascending=False, bins=None, dropna=True
1169+
self,
1170+
normalize: bool = False,
1171+
sort: bool = True,
1172+
ascending: bool = False,
1173+
bins=None,
1174+
dropna: bool = True,
11651175
):
11661176
"""
11671177
Return a Series containing counts of unique values.
@@ -1500,20 +1510,9 @@ def searchsorted(self, value, side="left", sorter=None) -> np.ndarray:
15001510
return algorithms.searchsorted(self._values, value, side=side, sorter=sorter)
15011511

15021512
def drop_duplicates(self, keep="first"):
1503-
if isinstance(self, ABCIndexClass):
1504-
if self.is_unique:
1505-
return self._shallow_copy()
1506-
15071513
duplicated = self.duplicated(keep=keep)
15081514
result = self[np.logical_not(duplicated)]
15091515
return result
15101516

15111517
def duplicated(self, keep="first"):
1512-
if isinstance(self, ABCIndexClass):
1513-
if self.is_unique:
1514-
return np.zeros(len(self), dtype=bool)
1515-
return duplicated(self, keep=keep)
1516-
else:
1517-
return self._constructor(
1518-
duplicated(self, keep=keep), index=self.index
1519-
).__finalize__(self, method="duplicated")
1518+
return duplicated(self._values, keep=keep)

pandas/core/indexes/base.py

+6
Original file line numberDiff line numberDiff line change
@@ -2366,6 +2366,9 @@ def drop_duplicates(self, keep="first"):
23662366
>>> idx.drop_duplicates(keep=False)
23672367
Index(['cow', 'beetle', 'hippo'], dtype='object')
23682368
"""
2369+
if self.is_unique:
2370+
return self._shallow_copy()
2371+
23692372
return super().drop_duplicates(keep=keep)
23702373

23712374
def duplicated(self, keep="first"):
@@ -2422,6 +2425,9 @@ def duplicated(self, keep="first"):
24222425
>>> idx.duplicated(keep=False)
24232426
array([ True, False, True, False, True])
24242427
"""
2428+
if self.is_unique:
2429+
# fastpath available bc we are immutable
2430+
return np.zeros(len(self), dtype=bool)
24252431
return super().duplicated(keep=keep)
24262432

24272433
def _get_unique_index(self, dropna: bool = False):

pandas/core/series.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -2053,7 +2053,9 @@ def duplicated(self, keep="first") -> "Series":
20532053
4 True
20542054
dtype: bool
20552055
"""
2056-
return super().duplicated(keep=keep)
2056+
res = base.IndexOpsMixin.duplicated(self, keep=keep)
2057+
result = self._constructor(res, index=self.index)
2058+
return result.__finalize__(self, method="duplicated")
20572059

20582060
def idxmin(self, axis=0, skipna=True, *args, **kwargs):
20592061
"""
@@ -4776,7 +4778,7 @@ def _convert_dtypes(
47764778

47774779
@doc(NDFrame.isna, klass=_shared_doc_kwargs["klass"])
47784780
def isna(self) -> "Series":
4779-
return super().isna()
4781+
return generic.NDFrame.isna(self)
47804782

47814783
@doc(NDFrame.isna, klass=_shared_doc_kwargs["klass"])
47824784
def isnull(self) -> "Series":

0 commit comments

Comments
 (0)