From 48482bac35222dd77688579bd6911664601bf320 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Fri, 12 Mar 2021 11:22:58 +0100 Subject: [PATCH 1/2] REF/PERF: move np.errstate out of core array_ops up to higher level --- pandas/core/arrays/numpy_.py | 3 ++- pandas/core/computation/expressions.py | 3 +-- pandas/core/frame.py | 36 ++++++++++++++------------ pandas/core/ops/__init__.py | 3 ++- pandas/core/ops/array_ops.py | 18 +++++++------ pandas/core/series.py | 6 +++-- 6 files changed, 39 insertions(+), 30 deletions(-) diff --git a/pandas/core/arrays/numpy_.py b/pandas/core/arrays/numpy_.py index 5ef3c24726924..85cb862a31776 100644 --- a/pandas/core/arrays/numpy_.py +++ b/pandas/core/arrays/numpy_.py @@ -376,7 +376,8 @@ def _cmp_method(self, other, op): other = other._ndarray pd_op = ops.get_array_op(op) - result = pd_op(self._ndarray, other) + with np.errstate(all="ignore"): + result = pd_op(self._ndarray, other) if op is divmod or op is ops.rdivmod: a, b = result diff --git a/pandas/core/computation/expressions.py b/pandas/core/computation/expressions.py index 05736578b6337..0dbe5e8d83741 100644 --- a/pandas/core/computation/expressions.py +++ b/pandas/core/computation/expressions.py @@ -71,8 +71,7 @@ def _evaluate_standard(op, op_str, a, b): """ if _TEST_MODE: _store_test_result(False) - with np.errstate(all="ignore"): - return op(a, b) + return op(a, b) def _can_use_numexpr(op, op_str, a, b, dtype_check): diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 98abe8eaffca8..b6dad0ade38ba 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -6556,7 +6556,8 @@ def _dispatch_frame_op(self, right, func, axis: Optional[int] = None): right = lib.item_from_zerodim(right) if not is_list_like(right): # i.e. scalar, faster than checking np.ndim(right) == 0 - bm = self._mgr.apply(array_op, right=right) + with np.errstate(all="ignore"): + bm = self._mgr.apply(array_op, right=right) return type(self)(bm) elif isinstance(right, DataFrame): @@ -6567,16 +6568,17 @@ def _dispatch_frame_op(self, right, func, axis: Optional[int] = None): # _frame_arith_method_with_reindex # TODO operate_blockwise expects a manager of the same type - bm = self._mgr.operate_blockwise( - # error: Argument 1 to "operate_blockwise" of "ArrayManager" has - # incompatible type "Union[ArrayManager, BlockManager]"; expected - # "ArrayManager" - # error: Argument 1 to "operate_blockwise" of "BlockManager" has - # incompatible type "Union[ArrayManager, BlockManager]"; expected - # "BlockManager" - right._mgr, # type: ignore[arg-type] - array_op, - ) + with np.errstate(all="ignore"): + bm = self._mgr.operate_blockwise( + # error: Argument 1 to "operate_blockwise" of "ArrayManager" has + # incompatible type "Union[ArrayManager, BlockManager]"; expected + # "ArrayManager" + # error: Argument 1 to "operate_blockwise" of "BlockManager" has + # incompatible type "Union[ArrayManager, BlockManager]"; expected + # "BlockManager" + right._mgr, # type: ignore[arg-type] + array_op, + ) return type(self)(bm) elif isinstance(right, Series) and axis == 1: @@ -6587,16 +6589,18 @@ def _dispatch_frame_op(self, right, func, axis: Optional[int] = None): # maybe_align_as_frame ensures we do not have an ndarray here assert not isinstance(right, np.ndarray) - arrays = [ - array_op(_left, _right) - for _left, _right in zip(self._iter_column_arrays(), right) - ] + with np.errstate(all="ignore"): + arrays = [ + array_op(_left, _right) + for _left, _right in zip(self._iter_column_arrays(), right) + ] elif isinstance(right, Series): assert right.index.equals(self.index) # Handle other cases later right = right._values - arrays = [array_op(left, right) for left in self._iter_column_arrays()] + with np.errstate(all="ignore"): + arrays = [array_op(left, right) for left in self._iter_column_arrays()] else: # Remaining cases have less-obvious dispatch rules diff --git a/pandas/core/ops/__init__.py b/pandas/core/ops/__init__.py index 8ace64fedacb9..869c96444e958 100644 --- a/pandas/core/ops/__init__.py +++ b/pandas/core/ops/__init__.py @@ -433,7 +433,8 @@ def f(self, other, axis=default_axis, level=None, fill_value=None): if isinstance(other, ABCDataFrame): # Another DataFrame - new_data = self._combine_frame(other, na_op, fill_value) + with np.errstate(all="ignore"): + new_data = self._combine_frame(other, na_op, fill_value) elif isinstance(other, ABCSeries): new_data = self._dispatch_frame_op(other, op, axis=axis) diff --git a/pandas/core/ops/array_ops.py b/pandas/core/ops/array_ops.py index 9153eb25032e7..f9960826a5c8f 100644 --- a/pandas/core/ops/array_ops.py +++ b/pandas/core/ops/array_ops.py @@ -106,8 +106,7 @@ def _masked_arith_op(x: np.ndarray, y, op): # See GH#5284, GH#5035, GH#19448 for historical reference if mask.any(): - with np.errstate(all="ignore"): - result[mask] = op(xrav[mask], yrav[mask]) + result[mask] = op(xrav[mask], yrav[mask]) else: if not is_scalar(y): @@ -126,8 +125,7 @@ def _masked_arith_op(x: np.ndarray, y, op): mask = np.where(y == 1, False, mask) if mask.any(): - with np.errstate(all="ignore"): - result[mask] = op(xrav[mask], y) + result[mask] = op(xrav[mask], y) result = maybe_upcast_putmask(result, ~mask) result = result.reshape(x.shape) # 2D compat @@ -179,6 +177,9 @@ def arithmetic_op(left: ArrayLike, right: Any, op): """ Evaluate an arithmetic operation `+`, `-`, `*`, `/`, `//`, `%`, `**`, ... + Note: the caller is responsible for ensuring that numpy warnings are + suppressed (with np.errstate(all="ignore")) if needed. + Parameters ---------- left : np.ndarray or ExtensionArray @@ -204,8 +205,7 @@ def arithmetic_op(left: ArrayLike, right: Any, op): res_values = op(lvalues, rvalues) else: - with np.errstate(all="ignore"): - res_values = _na_arithmetic_op(lvalues, rvalues, op) + res_values = _na_arithmetic_op(lvalues, rvalues, op) return res_values @@ -214,6 +214,9 @@ def comparison_op(left: ArrayLike, right: Any, op) -> ArrayLike: """ Evaluate a comparison operation `=`, `!=`, `>=`, `>`, `<=`, or `<`. + Note: the caller is responsible for ensuring that numpy warnings are + suppressed (with np.errstate(all="ignore")) if needed. + Parameters ---------- left : np.ndarray or ExtensionArray @@ -265,8 +268,7 @@ def comparison_op(left: ArrayLike, right: Any, op) -> ArrayLike: with warnings.catch_warnings(): # suppress warnings from numpy about element-wise comparison warnings.simplefilter("ignore", DeprecationWarning) - with np.errstate(all="ignore"): - res_values = _na_arithmetic_op(lvalues, rvalues, op, is_cmp=True) + res_values = _na_arithmetic_op(lvalues, rvalues, op, is_cmp=True) return res_values diff --git a/pandas/core/series.py b/pandas/core/series.py index 9feec7acae4c6..9b27ad27735c9 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -5067,7 +5067,8 @@ def _cmp_method(self, other, op): lvalues = self._values rvalues = extract_array(other, extract_numpy=True) - res_values = ops.comparison_op(lvalues, rvalues, op) + with np.errstate(all="ignore"): + res_values = ops.comparison_op(lvalues, rvalues, op) return self._construct_result(res_values, name=res_name) @@ -5087,7 +5088,8 @@ def _arith_method(self, other, op): lvalues = self._values rvalues = extract_array(other, extract_numpy=True) - result = ops.arithmetic_op(lvalues, rvalues, op) + with np.errstate(all="ignore"): + result = ops.arithmetic_op(lvalues, rvalues, op) return self._construct_result(result, name=res_name) From 4f4af5477cc015c1d4cc96eef02c577a3b2ca0d6 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Fri, 12 Mar 2021 19:06:28 +0100 Subject: [PATCH 2/2] remove in _combine_frame --- pandas/core/ops/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/core/ops/__init__.py b/pandas/core/ops/__init__.py index 869c96444e958..8ace64fedacb9 100644 --- a/pandas/core/ops/__init__.py +++ b/pandas/core/ops/__init__.py @@ -433,8 +433,7 @@ def f(self, other, axis=default_axis, level=None, fill_value=None): if isinstance(other, ABCDataFrame): # Another DataFrame - with np.errstate(all="ignore"): - new_data = self._combine_frame(other, na_op, fill_value) + new_data = self._combine_frame(other, na_op, fill_value) elif isinstance(other, ABCSeries): new_data = self._dispatch_frame_op(other, op, axis=axis)