def arithmetic_op( left: Union[np.ndarray, ABCExtensionArray], right: Any, op, str_rep: str, eval_kwargs: Mapping[str, bool], ): """ Evaluate an arithmetic operation `+`, `-`, `*`, `/`, `//`, `%`, `**`, ... Parameters ---------- left : np.ndarray or ExtensionArray right : object Cannot be a DataFrame or Index. Series is *not* excluded. op : {operator.add, operator.sub, ...} Or one of the reversed variants from roperator. str_rep : str Returns ------- ndarrray or ExtensionArray Or a 2-tuple of these in the case of divmod or rdivmod. """ from pandas.core.ops import maybe_upcast_for_op keep_null_freq = isinstance( right, ( ABCDatetimeIndex, ABCDatetimeArray, ABCTimedeltaIndex, ABCTimedeltaArray, Timestamp, ), ) # NB: We assume that extract_array has already been called on `left`, but # cannot make the same assumption about `right`. This is because we need # to define `keep_null_freq` before calling extract_array on it. lvalues = left rvalues = extract_array(right, extract_numpy=True) rvalues = maybe_upcast_for_op(rvalues, lvalues.shape) if should_extension_dispatch(left, rvalues) or isinstance( rvalues, (ABCTimedeltaArray, ABCDatetimeArray, Timestamp)): # TimedeltaArray, DatetimeArray, and Timestamp are included here # because they have `freq` attribute which is handled correctly # by dispatch_to_extension_op. res_values = dispatch_to_extension_op(op, lvalues, rvalues, keep_null_freq) else: with np.errstate(all="ignore"): res_values = na_arithmetic_op(lvalues, rvalues, op, str_rep, eval_kwargs) return res_values
def arithmetic_op(left: Union[np.ndarray, ABCExtensionArray], right: Any, op, str_rep: str): """ Evaluate an arithmetic operation `+`, `-`, `*`, `/`, `//`, `%`, `**`, ... Parameters ---------- left : np.ndarray or ExtensionArray right : object Cannot be a DataFrame or Index. Series is *not* excluded. op : {operator.add, operator.sub, ...} Or one of the reversed variants from roperator. str_rep : str Returns ------- ndarrray or ExtensionArray Or a 2-tuple of these in the case of divmod or rdivmod. """ from pandas.core.ops import maybe_upcast_for_op # NB: We assume that extract_array has already been called # on `left` and `right`. lvalues = left rvalues = right rvalues = maybe_upcast_for_op(rvalues, lvalues.shape) if should_extension_dispatch(left, rvalues) or isinstance( rvalues, (ABCTimedeltaArray, ABCDatetimeArray, Timestamp, Timedelta)): # TimedeltaArray, DatetimeArray, and Timestamp are included here # because they have `freq` attribute which is handled correctly # by dispatch_to_extension_op. # Timedelta is included because numexpr will fail on it, see GH#31457 res_values = dispatch_to_extension_op(op, lvalues, rvalues) else: with np.errstate(all="ignore"): res_values = na_arithmetic_op(lvalues, rvalues, op, str_rep) return res_values