diff --git a/pandas/core/base.py b/pandas/core/base.py index e2b19a3baed33..f907089f77132 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -23,7 +23,6 @@ from pandas._libs import lib from pandas._typing import ( - Axis, AxisInt, DtypeObj, IndexLabel, @@ -588,7 +587,8 @@ def to_numpy( values = np.asarray(values, dtype=dtype) else: values = values.copy() - values[np.asanyarray(self.isna())] = na_value + + values[np.asanyarray(isna(self))] = na_value result = np.asarray(values, dtype=dtype) @@ -608,50 +608,6 @@ def to_numpy( def empty(self) -> bool: return not self.size - def max(self, axis: AxisInt | None = None, skipna: bool = True, *args, **kwargs): - """ - Return the maximum value of the Index. - - Parameters - ---------- - axis : int, optional - For compatibility with NumPy. Only 0 or None are allowed. - skipna : bool, default True - Exclude NA/null values when showing the result. - *args, **kwargs - Additional arguments and keywords for compatibility with NumPy. - - Returns - ------- - scalar - Maximum value. - - See Also - -------- - Index.min : Return the minimum value in an Index. - Series.max : Return the maximum value in a Series. - DataFrame.max : Return the maximum values in a DataFrame. - - Examples - -------- - >>> idx = pd.Index([3, 2, 1]) - >>> idx.max() - 3 - - >>> idx = pd.Index(['c', 'b', 'a']) - >>> idx.max() - 'c' - - For a MultiIndex, the maximum is determined lexicographically. - - >>> idx = pd.MultiIndex.from_product([('a', 'b'), (2, 1)]) - >>> idx.max() - ('b', 2) - """ - nv.validate_minmax_axis(axis) - nv.validate_max(args, kwargs) - return nanops.nanmax(self._values, skipna=skipna) - @doc(op="max", oppose="min", value="largest") def argmax( self, axis: AxisInt | None = None, skipna: bool = True, *args, **kwargs @@ -722,50 +678,6 @@ def argmax( delegate, skipna=skipna ) - def min(self, axis: AxisInt | None = None, skipna: bool = True, *args, **kwargs): - """ - Return the minimum value of the Index. - - Parameters - ---------- - axis : {None} - Dummy argument for consistency with Series. - skipna : bool, default True - Exclude NA/null values when showing the result. - *args, **kwargs - Additional arguments and keywords for compatibility with NumPy. - - Returns - ------- - scalar - Minimum value. - - See Also - -------- - Index.max : Return the maximum value of the object. - Series.min : Return the minimum value in a Series. - DataFrame.min : Return the minimum values in a DataFrame. - - Examples - -------- - >>> idx = pd.Index([3, 2, 1]) - >>> idx.min() - 1 - - >>> idx = pd.Index(['c', 'b', 'a']) - >>> idx.min() - 'a' - - For a MultiIndex, the minimum is determined lexicographically. - - >>> idx = pd.MultiIndex.from_product([('a', 'b'), (2, 1)]) - >>> idx.min() - ('a', 1) - """ - nv.validate_minmax_axis(axis) - nv.validate_min(args, kwargs) - return nanops.nanmin(self._values, skipna=skipna) - @doc(argmax, op="min", oppose="max", value="smallest") def argmin( self, axis: AxisInt | None = None, skipna: bool = True, *args, **kwargs @@ -859,30 +771,6 @@ def hasnans(self) -> bool: # has no attribute "any" return bool(isna(self).any()) # type: ignore[union-attr] - def isna(self) -> npt.NDArray[np.bool_]: - return isna(self._values) - - def _reduce( - self, - op, - name: str, - *, - axis: Axis = 0, - skipna: bool = True, - numeric_only=None, - filter_type=None, - **kwds, - ): - """ - Perform the reduction type operation if we can. - """ - func = getattr(self, name, None) - if func is None: - raise TypeError( - f"{type(self).__name__} cannot perform the operation {name}" - ) - return func(skipna=skipna, **kwds) - @final def _map_values(self, mapper, na_action=None, convert: bool = True): """ diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index b57a8f2afee32..8b191897e9409 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -135,6 +135,7 @@ from pandas.core import ( arraylike, + nanops, ops, ) from pandas.core.accessor import CachedAccessor @@ -6984,8 +6985,46 @@ def argmax(self, axis=None, skipna: bool = True, *args, **kwargs) -> int: return -1 return super().argmax(skipna=skipna) - @doc(IndexOpsMixin.min) def min(self, axis=None, skipna: bool = True, *args, **kwargs): + """ + Return the minimum value of the Index. + + Parameters + ---------- + axis : {None} + Dummy argument for consistency with Series. + skipna : bool, default True + Exclude NA/null values when showing the result. + *args, **kwargs + Additional arguments and keywords for compatibility with NumPy. + + Returns + ------- + scalar + Minimum value. + + See Also + -------- + Index.max : Return the maximum value of the object. + Series.min : Return the minimum value in a Series. + DataFrame.min : Return the minimum values in a DataFrame. + + Examples + -------- + >>> idx = pd.Index([3, 2, 1]) + >>> idx.min() + 1 + + >>> idx = pd.Index(['c', 'b', 'a']) + >>> idx.min() + 'a' + + For a MultiIndex, the minimum is determined lexicographically. + + >>> idx = pd.MultiIndex.from_product([('a', 'b'), (2, 1)]) + >>> idx.min() + ('a', 1) + """ nv.validate_min(args, kwargs) nv.validate_minmax_axis(axis) @@ -7007,10 +7046,49 @@ def min(self, axis=None, skipna: bool = True, *args, **kwargs): if not self._is_multi and not isinstance(self._values, np.ndarray): return self._values._reduce(name="min", skipna=skipna) - return super().min(skipna=skipna) + return nanops.nanmin(self._values, skipna=skipna) - @doc(IndexOpsMixin.max) def max(self, axis=None, skipna: bool = True, *args, **kwargs): + """ + Return the maximum value of the Index. + + Parameters + ---------- + axis : int, optional + For compatibility with NumPy. Only 0 or None are allowed. + skipna : bool, default True + Exclude NA/null values when showing the result. + *args, **kwargs + Additional arguments and keywords for compatibility with NumPy. + + Returns + ------- + scalar + Maximum value. + + See Also + -------- + Index.min : Return the minimum value in an Index. + Series.max : Return the maximum value in a Series. + DataFrame.max : Return the maximum values in a DataFrame. + + Examples + -------- + >>> idx = pd.Index([3, 2, 1]) + >>> idx.max() + 3 + + >>> idx = pd.Index(['c', 'b', 'a']) + >>> idx.max() + 'c' + + For a MultiIndex, the maximum is determined lexicographically. + + >>> idx = pd.MultiIndex.from_product([('a', 'b'), (2, 1)]) + >>> idx.max() + ('b', 2) + """ + nv.validate_max(args, kwargs) nv.validate_minmax_axis(axis) @@ -7032,7 +7110,7 @@ def max(self, axis=None, skipna: bool = True, *args, **kwargs): if not self._is_multi and not isinstance(self._values, np.ndarray): return self._values._reduce(name="max", skipna=skipna) - return super().max(skipna=skipna) + return nanops.nanmax(self._values, skipna=skipna) # -------------------------------------------------------------------- diff --git a/pandas/core/series.py b/pandas/core/series.py index 9c91badc57ce3..a5e95e10eadfe 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -240,9 +240,10 @@ def wrapper(self): # Series class -# error: Definition of "max" in base class "IndexOpsMixin" is incompatible with -# definition in base class "NDFrame" -# error: Definition of "min" in base class "IndexOpsMixin" is incompatible with +# error: Cannot override final attribute "ndim" (previously declared in base +# class "NDFrame") +# error: Cannot override final attribute "size" (previously declared in base +# class "NDFrame") # definition in base class "NDFrame" class Series(base.IndexOpsMixin, NDFrame): # type: ignore[misc] """ @@ -5395,10 +5396,8 @@ def _convert_dtypes( return result # error: Cannot determine type of 'isna' - # error: Return type "Series" of "isna" incompatible with return type "ndarray - # [Any, dtype[bool_]]" in supertype "IndexOpsMixin" @doc(NDFrame.isna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type] - def isna(self) -> Series: # type: ignore[override] + def isna(self) -> Series: return NDFrame.isna(self) # error: Cannot determine type of 'isna' @@ -6092,8 +6091,7 @@ def all( ) @doc(make_doc("min", ndim=1)) - # error: Signature of "min" incompatible with supertype "IndexOpsMixin" - def min( # type: ignore[override] + def min( self, axis: Axis | None = 0, skipna: bool = True, @@ -6103,8 +6101,7 @@ def min( # type: ignore[override] return NDFrame.min(self, axis, skipna, numeric_only, **kwargs) @doc(make_doc("max", ndim=1)) - # error: Signature of "max" incompatible with supertype "IndexOpsMixin" - def max( # type: ignore[override] + def max( self, axis: Axis | None = 0, skipna: bool = True,