From f75156722573ccaf68232262aaa549f93431fb7b Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Thu, 26 Sep 2019 08:23:22 -0700 Subject: [PATCH 1/2] REF: simplify _combine_series_frame, unify align calls --- pandas/core/frame.py | 24 +++++++++++------------- pandas/core/ops/__init__.py | 19 ++++++++++--------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ed05691d33d07..7673b40ada487 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -5271,24 +5271,22 @@ def _arith_op(left, right): new_data = dispatch_fill_zeros(func, this.values, other.values, res_values) return this._construct_result(new_data) - def _combine_match_index(self, other, func, level=None): - left, right = self.align(other, join="outer", axis=0, level=level, copy=False) - # at this point we have `left.index.equals(right.index)` + def _combine_match_index(self, other, func): + # at this point we have `self.index.equals(other.index)` - if left._is_mixed_type or right._is_mixed_type: + if self._is_mixed_type or other._is_mixed_type: # operate column-wise; avoid costly object-casting in `.values` - new_data = ops.dispatch_to_series(left, right, func) + new_data = ops.dispatch_to_series(self, other, func) else: # fastpath --> operate directly on values with np.errstate(all="ignore"): - new_data = func(left.values.T, right.values).T - return left._construct_result(new_data) - - def _combine_match_columns(self, other: Series, func, level=None): - left, right = self.align(other, join="outer", axis=1, level=level, copy=False) - # at this point we have `left.columns.equals(right.index)` - new_data = ops.dispatch_to_series(left, right, func, axis="columns") - return left._construct_result(new_data) + new_data = func(self.values.T, other.values).T + return self._construct_result(new_data) + + def _combine_match_columns(self, other: Series, func): + # at this point we have `self.columns.equals(other.index)` + new_data = ops.dispatch_to_series(self, other, func, axis="columns") + return self._construct_result(new_data) def _construct_result(self, result) -> "DataFrame": """ diff --git a/pandas/core/ops/__init__.py b/pandas/core/ops/__init__.py index 06c0e9722c045..740e72dc28bf1 100644 --- a/pandas/core/ops/__init__.py +++ b/pandas/core/ops/__init__.py @@ -727,15 +727,16 @@ def _combine_series_frame(self, other, func, fill_value=None, axis=None, level=N "fill_value {fill} not supported.".format(fill=fill_value) ) - if axis is not None: - axis = self._get_axis_number(axis) - if axis == 0: - return self._combine_match_index(other, func, level=level) - else: - return self._combine_match_columns(other, func, level=level) - - # default axis is columns - return self._combine_match_columns(other, func, level=level) + if axis is None: + # default axis is columns + axis = 1 + + axis = self._get_axis_number(axis) + left, right = self.align(other, join="outer", axis=axis, level=level, copy=False) + if axis == 0: + return left._combine_match_index(right, func) + else: + return left._combine_match_columns(right, func) def _align_method_FRAME(left, right, axis): From 2ff817221cb3a0d284e80b3516429aebc5d8c293 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Thu, 26 Sep 2019 08:50:23 -0700 Subject: [PATCH 2/2] REF: push back _construct_result call --- pandas/core/frame.py | 7 +------ pandas/core/ops/__init__.py | 8 +++++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 7673b40ada487..9dc16eb132504 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -5281,12 +5281,7 @@ def _combine_match_index(self, other, func): # fastpath --> operate directly on values with np.errstate(all="ignore"): new_data = func(self.values.T, other.values).T - return self._construct_result(new_data) - - def _combine_match_columns(self, other: Series, func): - # at this point we have `self.columns.equals(other.index)` - new_data = ops.dispatch_to_series(self, other, func, axis="columns") - return self._construct_result(new_data) + return new_data def _construct_result(self, result) -> "DataFrame": """ diff --git a/pandas/core/ops/__init__.py b/pandas/core/ops/__init__.py index 740e72dc28bf1..88a923733c312 100644 --- a/pandas/core/ops/__init__.py +++ b/pandas/core/ops/__init__.py @@ -457,7 +457,7 @@ def column_op(a, b): return {i: func(a.iloc[:, i], b.iloc[:, i]) for i in range(len(a.columns))} elif isinstance(right, ABCSeries) and axis == "columns": - # We only get here if called via left._combine_match_columns, + # We only get here if called via _combine_frame_series, # in which case we specifically want to operate row-by-row assert right.index.equals(left.columns) @@ -734,9 +734,11 @@ def _combine_series_frame(self, other, func, fill_value=None, axis=None, level=N axis = self._get_axis_number(axis) left, right = self.align(other, join="outer", axis=axis, level=level, copy=False) if axis == 0: - return left._combine_match_index(right, func) + new_data = left._combine_match_index(right, func) else: - return left._combine_match_columns(right, func) + new_data = dispatch_to_series(left, right, func, axis="columns") + + return left._construct_result(new_data) def _align_method_FRAME(left, right, axis):