Skip to content

Commit

Permalink
REF: Consolidate alignment calls in DataFrame ops (pandas-dev#28638)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel authored and Nico Cernek committed Jan 1, 2020
1 parent e5cc054 commit 8d810b4
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 22 deletions.
19 changes: 6 additions & 13 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -5279,24 +5279,17 @@ 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 new_data

def _construct_result(self, result) -> "DataFrame":
"""
Expand Down
21 changes: 12 additions & 9 deletions pandas/core/ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,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)

Expand Down Expand Up @@ -613,15 +613,18 @@ 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)
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:
new_data = left._combine_match_index(right, func)
else:
new_data = dispatch_to_series(left, right, func, axis="columns")

# default axis is columns
return self._combine_match_columns(other, func, level=level)
return left._construct_result(new_data)


def _align_method_FRAME(left, right, axis):
Expand Down

0 comments on commit 8d810b4

Please sign in to comment.