diff --git a/pandas/core/array_algos/masked_reductions.py b/pandas/core/array_algos/masked_reductions.py index 3f4625e2b712a..bce6f1aafb2c5 100644 --- a/pandas/core/array_algos/masked_reductions.py +++ b/pandas/core/array_algos/masked_reductions.py @@ -17,6 +17,7 @@ def _sumprod( func: Callable, values: np.ndarray, mask: np.ndarray, + *, skipna: bool = True, min_count: int = 0, ): @@ -52,19 +53,25 @@ def _sumprod( return func(values, where=~mask) -def sum(values: np.ndarray, mask: np.ndarray, skipna: bool = True, min_count: int = 0): +def sum( + values: np.ndarray, mask: np.ndarray, *, skipna: bool = True, min_count: int = 0 +): return _sumprod( np.sum, values=values, mask=mask, skipna=skipna, min_count=min_count ) -def prod(values: np.ndarray, mask: np.ndarray, skipna: bool = True, min_count: int = 0): +def prod( + values: np.ndarray, mask: np.ndarray, *, skipna: bool = True, min_count: int = 0 +): return _sumprod( np.prod, values=values, mask=mask, skipna=skipna, min_count=min_count ) -def _minmax(func: Callable, values: np.ndarray, mask: np.ndarray, skipna: bool = True): +def _minmax( + func: Callable, values: np.ndarray, mask: np.ndarray, *, skipna: bool = True +): """ Reduction for 1D masked array. @@ -94,9 +101,9 @@ def _minmax(func: Callable, values: np.ndarray, mask: np.ndarray, skipna: bool = return libmissing.NA -def min(values: np.ndarray, mask: np.ndarray, skipna: bool = True): +def min(values: np.ndarray, mask: np.ndarray, *, skipna: bool = True): return _minmax(np.min, values=values, mask=mask, skipna=skipna) -def max(values: np.ndarray, mask: np.ndarray, skipna: bool = True): +def max(values: np.ndarray, mask: np.ndarray, *, skipna: bool = True): return _minmax(np.max, values=values, mask=mask, skipna=skipna) diff --git a/pandas/core/arrays/_mixins.py b/pandas/core/arrays/_mixins.py index 63c414d96c8de..a8c0e77270dfc 100644 --- a/pandas/core/arrays/_mixins.py +++ b/pandas/core/arrays/_mixins.py @@ -54,6 +54,7 @@ def _validate_scalar(self, value): def take( self: _T, indices: Sequence[int], + *, allow_fill: bool = False, fill_value: Any = None, axis: int = 0, @@ -246,7 +247,7 @@ def fillna(self: _T, value=None, method=None, limit=None) -> _T: # ------------------------------------------------------------------------ # Reductions - def _reduce(self, name: str, skipna: bool = True, **kwargs): + def _reduce(self, name: str, *, skipna: bool = True, **kwargs): meth = getattr(self, name, None) if meth: return meth(skipna=skipna, **kwargs) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index be105fd1f2a46..afbddc53804ac 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -173,7 +173,7 @@ class ExtensionArray: # ------------------------------------------------------------------------ @classmethod - def _from_sequence(cls, scalars, dtype=None, copy=False): + def _from_sequence(cls, scalars, *, dtype=None, copy=False): """ Construct a new ExtensionArray from a sequence of scalars. @@ -195,7 +195,7 @@ def _from_sequence(cls, scalars, dtype=None, copy=False): raise AbstractMethodError(cls) @classmethod - def _from_sequence_of_strings(cls, strings, dtype=None, copy=False): + def _from_sequence_of_strings(cls, strings, *, dtype=None, copy=False): """ Construct a new ExtensionArray from a sequence of strings. @@ -922,7 +922,11 @@ def repeat(self, repeats, axis=None): # ------------------------------------------------------------------------ def take( - self, indices: Sequence[int], allow_fill: bool = False, fill_value: Any = None + self, + indices: Sequence[int], + *, + allow_fill: bool = False, + fill_value: Any = None, ) -> "ExtensionArray": """ Take elements from an array. @@ -1153,7 +1157,7 @@ def _concat_same_type( # of objects _can_hold_na = True - def _reduce(self, name: str, skipna: bool = True, **kwargs): + def _reduce(self, name: str, *, skipna: bool = True, **kwargs): """ Return a scalar result of performing the reduction operation. diff --git a/pandas/core/arrays/boolean.py b/pandas/core/arrays/boolean.py index 21306455573b8..c6c7396a980b0 100644 --- a/pandas/core/arrays/boolean.py +++ b/pandas/core/arrays/boolean.py @@ -273,7 +273,9 @@ def dtype(self) -> BooleanDtype: return self._dtype @classmethod - def _from_sequence(cls, scalars, dtype=None, copy: bool = False) -> "BooleanArray": + def _from_sequence( + cls, scalars, *, dtype=None, copy: bool = False + ) -> "BooleanArray": if dtype: assert dtype == "boolean" values, mask = coerce_to_array(scalars, copy=copy) @@ -281,7 +283,7 @@ def _from_sequence(cls, scalars, dtype=None, copy: bool = False) -> "BooleanArra @classmethod def _from_sequence_of_strings( - cls, strings: List[str], dtype=None, copy: bool = False + cls, strings: List[str], *, dtype=None, copy: bool = False ) -> "BooleanArray": def map_string(s): if isna(s): @@ -294,7 +296,7 @@ def map_string(s): raise ValueError(f"{s} cannot be cast to bool") scalars = [map_string(x) for x in strings] - return cls._from_sequence(scalars, dtype, copy) + return cls._from_sequence(scalars, dtype=dtype, copy=copy) _HANDLED_TYPES = (np.ndarray, numbers.Number, bool, np.bool_) @@ -682,12 +684,12 @@ def _arith_method(self, other, op): return self._maybe_mask_result(result, mask, other, op_name) - def _reduce(self, name: str, skipna: bool = True, **kwargs): + def _reduce(self, name: str, *, skipna: bool = True, **kwargs): if name in {"any", "all"}: return getattr(self, name)(skipna=skipna, **kwargs) - return super()._reduce(name, skipna, **kwargs) + return super()._reduce(name, skipna=skipna, **kwargs) def _maybe_mask_result(self, result, mask, other, op_name: str): """ diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index edbf24ca87f5c..51f3c16f3f467 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -385,7 +385,7 @@ def _constructor(self) -> Type["Categorical"]: return Categorical @classmethod - def _from_sequence(cls, scalars, dtype=None, copy=False): + def _from_sequence(cls, scalars, *, dtype=None, copy=False): return Categorical(scalars, dtype=dtype) def astype(self, dtype: Dtype, copy: bool = True) -> ArrayLike: diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 905242bfdd8ad..a05dc717f83c1 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -301,7 +301,7 @@ def _simple_new( return result @classmethod - def _from_sequence(cls, scalars, dtype=None, copy: bool = False): + def _from_sequence(cls, scalars, *, dtype=None, copy: bool = False): return cls._from_sequence_not_strict(scalars, dtype=dtype, copy=copy) @classmethod diff --git a/pandas/core/arrays/floating.py b/pandas/core/arrays/floating.py index 4cfaae23e4389..a5ebdd8d963e2 100644 --- a/pandas/core/arrays/floating.py +++ b/pandas/core/arrays/floating.py @@ -275,16 +275,18 @@ def __init__(self, values: np.ndarray, mask: np.ndarray, copy: bool = False): super().__init__(values, mask, copy=copy) @classmethod - def _from_sequence(cls, scalars, dtype=None, copy: bool = False) -> "FloatingArray": + def _from_sequence( + cls, scalars, *, dtype=None, copy: bool = False + ) -> "FloatingArray": values, mask = coerce_to_array(scalars, dtype=dtype, copy=copy) return FloatingArray(values, mask) @classmethod def _from_sequence_of_strings( - cls, strings, dtype=None, copy: bool = False + cls, strings, *, dtype=None, copy: bool = False ) -> "FloatingArray": scalars = to_numeric(strings, errors="raise") - return cls._from_sequence(scalars, dtype, copy) + return cls._from_sequence(scalars, dtype=dtype, copy=copy) _HANDLED_TYPES = (np.ndarray, numbers.Number) diff --git a/pandas/core/arrays/integer.py b/pandas/core/arrays/integer.py index e3d19e53e4517..c9d7632e39228 100644 --- a/pandas/core/arrays/integer.py +++ b/pandas/core/arrays/integer.py @@ -358,15 +358,17 @@ def __abs__(self): return type(self)(np.abs(self._data), self._mask) @classmethod - def _from_sequence(cls, scalars, dtype=None, copy: bool = False) -> "IntegerArray": + def _from_sequence( + cls, scalars, *, dtype=None, copy: bool = False + ) -> "IntegerArray": return integer_array(scalars, dtype=dtype, copy=copy) @classmethod def _from_sequence_of_strings( - cls, strings, dtype=None, copy: bool = False + cls, strings, *, dtype=None, copy: bool = False ) -> "IntegerArray": scalars = to_numeric(strings, errors="raise") - return cls._from_sequence(scalars, dtype, copy) + return cls._from_sequence(scalars, dtype=dtype, copy=copy) _HANDLED_TYPES = (np.ndarray, numbers.Number) diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index 7b10334804ef9..a2eb506c6747a 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -227,7 +227,7 @@ def _simple_new(cls, data, closed="right"): return result @classmethod - def _from_sequence(cls, scalars, dtype=None, copy=False): + def _from_sequence(cls, scalars, *, dtype=None, copy=False): return cls(scalars, dtype=dtype, copy=copy) @classmethod @@ -788,7 +788,7 @@ def shift(self, periods: int = 1, fill_value: object = None) -> "IntervalArray": b = empty return self._concat_same_type([a, b]) - def take(self, indices, allow_fill=False, fill_value=None, axis=None, **kwargs): + def take(self, indices, *, allow_fill=False, fill_value=None, axis=None, **kwargs): """ Take elements from the IntervalArray. diff --git a/pandas/core/arrays/masked.py b/pandas/core/arrays/masked.py index b633f268049e5..9cc4cc72e4c8e 100644 --- a/pandas/core/arrays/masked.py +++ b/pandas/core/arrays/masked.py @@ -269,6 +269,7 @@ def _concat_same_type(cls: Type[BaseMaskedArrayT], to_concat) -> BaseMaskedArray def take( self: BaseMaskedArrayT, indexer, + *, allow_fill: bool = False, fill_value: Optional[Scalar] = None, ) -> BaseMaskedArrayT: @@ -357,7 +358,7 @@ def value_counts(self, dropna: bool = True) -> "Series": return Series(counts, index=index) - def _reduce(self, name: str, skipna: bool = True, **kwargs): + def _reduce(self, name: str, *, skipna: bool = True, **kwargs): data = self._data mask = self._mask diff --git a/pandas/core/arrays/numpy_.py b/pandas/core/arrays/numpy_.py index e1a424b719a4a..9419f111cc869 100644 --- a/pandas/core/arrays/numpy_.py +++ b/pandas/core/arrays/numpy_.py @@ -172,7 +172,9 @@ def __init__(self, values: Union[np.ndarray, "PandasArray"], copy: bool = False) self._dtype = PandasDtype(values.dtype) @classmethod - def _from_sequence(cls, scalars, dtype=None, copy: bool = False) -> "PandasArray": + def _from_sequence( + cls, scalars, *, dtype=None, copy: bool = False + ) -> "PandasArray": if isinstance(dtype, PandasDtype): dtype = dtype._dtype diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 8de84a0187e95..80882acceb56a 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -192,6 +192,7 @@ def _simple_new( def _from_sequence( cls: Type["PeriodArray"], scalars: Union[Sequence[Optional[Period]], AnyArrayLike], + *, dtype: Optional[PeriodDtype] = None, copy: bool = False, ) -> "PeriodArray": @@ -214,9 +215,9 @@ def _from_sequence( @classmethod def _from_sequence_of_strings( - cls, strings, dtype=None, copy=False + cls, strings, *, dtype=None, copy=False ) -> "PeriodArray": - return cls._from_sequence(strings, dtype, copy) + return cls._from_sequence(strings, dtype=dtype, copy=copy) @classmethod def _from_datetime64(cls, data, freq, tz=None) -> "PeriodArray": diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index 9152ce72d75aa..d976526955ac2 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -484,7 +484,7 @@ def __setitem__(self, key, value): raise TypeError(msg) @classmethod - def _from_sequence(cls, scalars, dtype=None, copy=False): + def _from_sequence(cls, scalars, *, dtype=None, copy=False): return cls(scalars, dtype=dtype) @classmethod @@ -809,7 +809,7 @@ def _get_val_at(self, loc): val = maybe_box_datetimelike(val, self.sp_values.dtype) return val - def take(self, indices, allow_fill=False, fill_value=None) -> "SparseArray": + def take(self, indices, *, allow_fill=False, fill_value=None) -> "SparseArray": if is_scalar(indices): raise ValueError(f"'indices' must be an array, not a scalar '{indices}'.") indices = np.asarray(indices, dtype=np.int32) @@ -1156,7 +1156,7 @@ def nonzero(self): # Reductions # ------------------------------------------------------------------------ - def _reduce(self, name: str, skipna: bool = True, **kwargs): + def _reduce(self, name: str, *, skipna: bool = True, **kwargs): method = getattr(self, name, None) if method is None: diff --git a/pandas/core/arrays/string_.py b/pandas/core/arrays/string_.py index 8231a5fa0509b..b17481c8e5f88 100644 --- a/pandas/core/arrays/string_.py +++ b/pandas/core/arrays/string_.py @@ -198,7 +198,7 @@ def _validate(self): ) @classmethod - def _from_sequence(cls, scalars, dtype=None, copy=False): + def _from_sequence(cls, scalars, *, dtype=None, copy=False): if dtype: assert dtype == "string" @@ -226,7 +226,7 @@ def _from_sequence(cls, scalars, dtype=None, copy=False): return new_string_array @classmethod - def _from_sequence_of_strings(cls, strings, dtype=None, copy=False): + def _from_sequence_of_strings(cls, strings, *, dtype=None, copy=False): return cls._from_sequence(strings, dtype=dtype, copy=copy) def __arrow_array__(self, type=None): @@ -295,7 +295,7 @@ def astype(self, dtype, copy=True): return super().astype(dtype, copy) - def _reduce(self, name: str, skipna: bool = True, **kwargs): + def _reduce(self, name: str, *, skipna: bool = True, **kwargs): if name in ["min", "max"]: return getattr(self, name)(skipna=skipna) diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 8a87df18b6adb..a75d411b4a40c 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -219,7 +219,7 @@ def _simple_new( @classmethod def _from_sequence( - cls, data, dtype=TD64NS_DTYPE, copy: bool = False + cls, data, *, dtype=TD64NS_DTYPE, copy: bool = False ) -> "TimedeltaArray": if dtype: _validate_td64_dtype(dtype) diff --git a/pandas/core/base.py b/pandas/core/base.py index c91e4db004f2a..b979298fa53f6 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -785,6 +785,7 @@ def _reduce( self, op, name: str, + *, axis=0, skipna=True, numeric_only=None, diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 049d2c4888a69..11b83a393dcc0 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -8719,6 +8719,7 @@ def _reduce( self, op, name: str, + *, axis=0, skipna=True, numeric_only=None, diff --git a/pandas/core/series.py b/pandas/core/series.py index e4a805a18bcdb..237c1c9a85575 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -4190,7 +4190,15 @@ def f(x): ) def _reduce( - self, op, name, axis=0, skipna=True, numeric_only=None, filter_type=None, **kwds + self, + op, + name: str, + *, + axis=0, + skipna=True, + numeric_only=None, + filter_type=None, + **kwds, ): """ Perform a reduction operation. diff --git a/pandas/tests/extension/arrow/arrays.py b/pandas/tests/extension/arrow/arrays.py index 04ce705690cf3..65c5102e22997 100644 --- a/pandas/tests/extension/arrow/arrays.py +++ b/pandas/tests/extension/arrow/arrays.py @@ -159,7 +159,7 @@ def _concat_same_type(cls, to_concat): def __invert__(self): return type(self).from_scalars(~self._data.to_pandas()) - def _reduce(self, name: str, skipna: bool = True, **kwargs): + def _reduce(self, name: str, *, skipna: bool = True, **kwargs): if skipna: arr = self[~self.isna()] else: diff --git a/pandas/tests/extension/decimal/array.py b/pandas/tests/extension/decimal/array.py index 3d1ebb01d632f..9ede9c7fbd0fd 100644 --- a/pandas/tests/extension/decimal/array.py +++ b/pandas/tests/extension/decimal/array.py @@ -178,7 +178,7 @@ def _formatter(self, boxed=False): def _concat_same_type(cls, to_concat): return cls(np.concatenate([x._data for x in to_concat])) - def _reduce(self, name: str, skipna: bool = True, **kwargs): + def _reduce(self, name: str, *, skipna: bool = True, **kwargs): if skipna: # If we don't have any NAs, we can ignore skipna