Skip to content
6 changes: 5 additions & 1 deletion pandas/core/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Generic data algorithms. This module is experimental at the moment and not
intended for public consumption
"""
import abc
import operator
from textwrap import dedent
from typing import TYPE_CHECKING, Dict, Optional, Tuple, Union
Expand Down Expand Up @@ -1065,7 +1066,7 @@ def _get_score(at):
# --------------- #


class SelectN:
class SelectN(abc.ABC):
def __init__(self, obj, n: int, keep: str):
self.obj = obj
self.n = n
Expand All @@ -1090,6 +1091,9 @@ def is_valid_dtype_n_method(dtype) -> bool:
is_numeric_dtype(dtype) and not is_complex_dtype(dtype)
) or needs_i8_conversion(dtype)

@abc.abstractmethod
def compute(self, method): ...


class SelectNSeries(SelectN):
"""
Expand Down
3 changes: 3 additions & 0 deletions pandas/core/apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ def get_result(self):
""" compute the results """
# dispatch to agg
if is_list_like(self.f) or is_dict_like(self.f):
if "axis" in self.kwds:
self.kwds.pop("axis")

return self.obj.aggregate(self.f, axis=self.axis, *self.args, **self.kwds)

# all empty
Expand Down
76 changes: 45 additions & 31 deletions pandas/core/arrays/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from pandas._libs import lib
from pandas._typing import ArrayLike
from typing_extensions import Protocol
from pandas.compat import set_function_name
from pandas.compat.numpy import function as nv
from pandas.errors import AbstractMethodError
Expand Down Expand Up @@ -1053,6 +1054,19 @@ def __hash__(self):
raise TypeError(f"unhashable type: {repr(type(self).__name__)}")


class OpsExtendable(Protocol):

@classmethod
def _create_arithmetic_method(cls, op): ...

@classmethod
def _create_comparison_method(cls, op): ...

@classmethod
def _create_logical_method(cls, op): ...



class ExtensionOpsMixin:
"""
A base class for linking the operators to their dunder names.
Expand All @@ -1065,41 +1079,41 @@ class ExtensionOpsMixin:
"""

@classmethod
def _add_arithmetic_ops(cls):
cls.__add__ = cls._create_arithmetic_method(operator.add)
cls.__radd__ = cls._create_arithmetic_method(ops.radd)
cls.__sub__ = cls._create_arithmetic_method(operator.sub)
cls.__rsub__ = cls._create_arithmetic_method(ops.rsub)
cls.__mul__ = cls._create_arithmetic_method(operator.mul)
cls.__rmul__ = cls._create_arithmetic_method(ops.rmul)
cls.__pow__ = cls._create_arithmetic_method(operator.pow)
cls.__rpow__ = cls._create_arithmetic_method(ops.rpow)
cls.__mod__ = cls._create_arithmetic_method(operator.mod)
cls.__rmod__ = cls._create_arithmetic_method(ops.rmod)
cls.__floordiv__ = cls._create_arithmetic_method(operator.floordiv)
cls.__rfloordiv__ = cls._create_arithmetic_method(ops.rfloordiv)
cls.__truediv__ = cls._create_arithmetic_method(operator.truediv)
cls.__rtruediv__ = cls._create_arithmetic_method(ops.rtruediv)
cls.__divmod__ = cls._create_arithmetic_method(divmod)
cls.__rdivmod__ = cls._create_arithmetic_method(ops.rdivmod)
def _add_arithmetic_ops(cls: OpsExtendable):
setattr(cls, "__add__", cls._create_arithmetic_method(operator.add))
setattr(cls, "__radd__", cls._create_arithmetic_method(ops.radd))
setattr(cls, "__sub__", cls._create_arithmetic_method(operator.sub))
setattr(cls, "__rsub__", cls._create_arithmetic_method(ops.rsub))
setattr(cls, "__mul__", cls._create_arithmetic_method(operator.mul))
setattr(cls, "__rmul__", cls._create_arithmetic_method(ops.rmul))
setattr(cls, "__pow__", cls._create_arithmetic_method(operator.pow))
setattr(cls, "__rpow__", cls._create_arithmetic_method(ops.rpow))
setattr(cls, "__mod__", cls._create_arithmetic_method(operator.mod))
setattr(cls, "__rmod__", cls._create_arithmetic_method(ops.rmod))
setattr(cls, "__floordiv__", cls._create_arithmetic_method(operator.floordiv))
setattr(cls, "__rfloordiv__", cls._create_arithmetic_method(ops.rfloordiv))
setattr(cls, "__truediv__", cls._create_arithmetic_method(operator.truediv))
setattr(cls, "__rtruediv__", cls._create_arithmetic_method(ops.rtruediv))
setattr(cls, "__divmod__", cls._create_arithmetic_method(divmod))
setattr(cls, "__rdivmod__", cls._create_arithmetic_method(ops.rdivmod))

@classmethod
def _add_comparison_ops(cls):
cls.__eq__ = cls._create_comparison_method(operator.eq)
cls.__ne__ = cls._create_comparison_method(operator.ne)
cls.__lt__ = cls._create_comparison_method(operator.lt)
cls.__gt__ = cls._create_comparison_method(operator.gt)
cls.__le__ = cls._create_comparison_method(operator.le)
cls.__ge__ = cls._create_comparison_method(operator.ge)
def _add_comparison_ops(cls: OpsExtendable):
setattr(cls, "__eq__", cls._create_comparison_method(operator.eq))
setattr(cls, "__ne__", cls._create_comparison_method(operator.ne))
setattr(cls, "__lt__", cls._create_comparison_method(operator.lt))
setattr(cls, "__gt__", cls._create_comparison_method(operator.gt))
setattr(cls, "__le__", cls._create_comparison_method(operator.le))
setattr(cls, "__ge__", cls._create_comparison_method(operator.ge))

@classmethod
def _add_logical_ops(cls):
cls.__and__ = cls._create_logical_method(operator.and_)
cls.__rand__ = cls._create_logical_method(ops.rand_)
cls.__or__ = cls._create_logical_method(operator.or_)
cls.__ror__ = cls._create_logical_method(ops.ror_)
cls.__xor__ = cls._create_logical_method(operator.xor)
cls.__rxor__ = cls._create_logical_method(ops.rxor)
def _add_logical_ops(cls: OpsExtendable):
setattr(cls, "__and__", cls._create_logical_method(operator.and_))
setattr(cls, "__rand__", cls._create_logical_method(ops.rand_))
setattr(cls, "__or__", cls._create_logical_method(operator.or_))
setattr(cls, "__ror__", cls._create_logical_method(ops.ror_))
setattr(cls, "__xor__", cls._create_logical_method(operator.xor))
setattr(cls, "__rxor__", cls._create_logical_method(ops.rxor))


class ExtensionScalarOpsMixin(ExtensionOpsMixin):
Expand Down
Loading