Evaluate the frame operation func(left, right) by evaluating column-by-column, dispatching to the Series implementation. Parameters ---------- right : scalar, Series, or DataFrame func : arithmetic or comparison operator axis : {None, 0, 1}
(
self, right, func: Callable, axis: AxisInt | None = None
)
| 9156 | _logical_method = _arith_method |
| 9157 | |
| 9158 | def _dispatch_frame_op( |
| 9159 | self, right, func: Callable, axis: AxisInt | None = None |
| 9160 | ) -> DataFrame: |
| 9161 | """ |
| 9162 | Evaluate the frame operation func(left, right) by evaluating |
| 9163 | column-by-column, dispatching to the Series implementation. |
| 9164 | |
| 9165 | Parameters |
| 9166 | ---------- |
| 9167 | right : scalar, Series, or DataFrame |
| 9168 | func : arithmetic or comparison operator |
| 9169 | axis : {None, 0, 1} |
| 9170 | |
| 9171 | Returns |
| 9172 | ------- |
| 9173 | DataFrame |
| 9174 | |
| 9175 | Notes |
| 9176 | ----- |
| 9177 | Caller is responsible for setting np.errstate where relevant. |
| 9178 | """ |
| 9179 | # Get the appropriate array-op to apply to each column/block's values. |
| 9180 | array_op = ops.get_array_op(func) |
| 9181 | |
| 9182 | right = lib.item_from_zerodim(right) |
| 9183 | if not is_list_like(right): |
| 9184 | # i.e. scalar, faster than checking np.ndim(right) == 0 |
| 9185 | bm = self._mgr.apply(array_op, right=right) |
| 9186 | return self._constructor_from_mgr(bm, axes=bm.axes) |
| 9187 | |
| 9188 | elif isinstance(right, DataFrame): |
| 9189 | assert self.index.equals(right.index) |
| 9190 | assert self.columns.equals(right.columns) |
| 9191 | # TODO: The previous assertion `assert right._indexed_same(self)` |
| 9192 | # fails in cases with empty columns reached via |
| 9193 | # _frame_arith_method_with_reindex |
| 9194 | |
| 9195 | # TODO operate_blockwise expects a manager of the same type |
| 9196 | bm = self._mgr.operate_blockwise( |
| 9197 | right._mgr, |
| 9198 | array_op, |
| 9199 | ) |
| 9200 | return self._constructor_from_mgr(bm, axes=bm.axes) |
| 9201 | |
| 9202 | elif isinstance(right, Series) and axis == 1: |
| 9203 | # axis=1 means we want to operate row-by-row |
| 9204 | assert right.index.equals(self.columns) |
| 9205 | |
| 9206 | right = right._values |
| 9207 | # maybe_align_as_frame ensures we do not have an ndarray here |
| 9208 | assert not isinstance(right, np.ndarray) |
| 9209 | |
| 9210 | arrays = [ |
| 9211 | array_op(_left, _right) |
| 9212 | for _left, _right in zip(self._iter_column_arrays(), right, strict=True) |
| 9213 | ] |
| 9214 | |
| 9215 | elif isinstance(right, Series): |
no test coverage detected