From 9105713ad0e8c859a9f1e91e80c54daad5fb9172 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Thu, 12 Sep 2019 08:11:46 -0700 Subject: [PATCH] REF: prepare Series arith op to be refactored to array op --- pandas/core/ops/__init__.py | 16 ++++++------ pandas/core/ops/array_ops.py | 48 ++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/pandas/core/ops/__init__.py b/pandas/core/ops/__init__.py index 90fb3b8685c93..baa978c32b2c3 100644 --- a/pandas/core/ops/__init__.py +++ b/pandas/core/ops/__init__.py @@ -40,7 +40,11 @@ from pandas._typing import ArrayLike from pandas.core.construction import array, extract_array -from pandas.core.ops.array_ops import comp_method_OBJECT_ARRAY, define_na_arithmetic_op +from pandas.core.ops.array_ops import ( + comp_method_OBJECT_ARRAY, + define_na_arithmetic_op, + na_arithmetic_op, +) from pandas.core.ops.docstrings import ( _arith_doc_FRAME, _flex_comp_doc_FRAME, @@ -616,20 +620,18 @@ def _arith_method_SERIES(cls, op, special): _construct_divmod_result if op in [divmod, rdivmod] else _construct_result ) - na_op = define_na_arithmetic_op(op, str_rep, eval_kwargs) - def wrapper(left, right): if isinstance(right, ABCDataFrame): return NotImplemented + left, right = _align_method_SERIES(left, right) + res_name = get_op_result_name(left, right) + keep_null_freq = isinstance( right, (ABCDatetimeIndex, ABCDatetimeArray, ABCTimedeltaIndex, ABCTimedeltaArray), ) - left, right = _align_method_SERIES(left, right) - res_name = get_op_result_name(left, right) - lvalues = extract_array(left, extract_numpy=True) rvalues = extract_array(right, extract_numpy=True) @@ -646,7 +648,7 @@ def wrapper(left, right): else: with np.errstate(all="ignore"): - result = na_op(lvalues, rvalues) + result = na_arithmetic_op(lvalues, rvalues, op, str_rep, eval_kwargs) # We do not pass dtype to ensure that the Series constructor # does inference in the case where `result` has object-dtype. diff --git a/pandas/core/ops/array_ops.py b/pandas/core/ops/array_ops.py index f5f6d77676f1f..d8b00bc629d44 100644 --- a/pandas/core/ops/array_ops.py +++ b/pandas/core/ops/array_ops.py @@ -98,31 +98,37 @@ def masked_arith_op(x, y, op): def define_na_arithmetic_op(op, str_rep, eval_kwargs): def na_op(x, y): - """ - Return the result of evaluating op on the passed in values. + return na_arithmetic_op(x, y, op, str_rep, eval_kwargs) - If native types are not compatible, try coersion to object dtype. + return na_op - Parameters - ---------- - x : array-like - y : array-like or scalar - Returns - ------- - array-like +def na_arithmetic_op(left, right, op, str_rep, eval_kwargs): + """ + Return the result of evaluating op on the passed in values. - Raises - ------ - TypeError : invalid operation - """ - import pandas.core.computation.expressions as expressions + If native types are not compatible, try coersion to object dtype. - try: - result = expressions.evaluate(op, str_rep, x, y, **eval_kwargs) - except TypeError: - result = masked_arith_op(x, y, op) + Parameters + ---------- + left : np.ndarray + right : np.ndarray or scalar + str_rep : str or None + eval_kwargs : kwargs to pass to expressions + + Returns + ------- + array-like + + Raises + ------ + TypeError : invalid operation + """ + import pandas.core.computation.expressions as expressions - return missing.dispatch_fill_zeros(op, x, y, result) + try: + result = expressions.evaluate(op, str_rep, left, right, **eval_kwargs) + except TypeError: + result = masked_arith_op(left, right, op) - return na_op + return missing.dispatch_fill_zeros(op, left, right, result)