Repository: modin-project/modin

Issue:
Don't trigger axes computation when doing binary operations
When we do a binary operation and return a Series object, we don't need to trigger axes computation in columnarize.



Discussion:

Resolving patch:
diff --git a/modin/core/dataframe/algebra/binary.py b/modin/core/dataframe/algebra/binary.py
--- a/modin/core/dataframe/algebra/binary.py
+++ b/modin/core/dataframe/algebra/binary.py
@@ -15,6 +15,7 @@
 
 import numpy as np
 import pandas
+from pandas.api.types import is_scalar
 
 from .operator import Operator
 
@@ -195,6 +196,8 @@ def caller(
                 Result of binary function.
             """
             axis = kwargs.get("axis", 0)
+            shape_hint = None
+            self_columns = query_compiler._modin_frame._columns_cache
             if isinstance(other, type(query_compiler)):
                 if broadcast:
                     assert (
@@ -206,6 +209,17 @@ def caller(
                     # column or row as a single-column Modin DataFrame
                     if axis == 1:
                         other = other.transpose()
+
+                    if (
+                        self_columns is not None
+                        and other._modin_frame._columns_cache is not None
+                    ):
+                        if (
+                            len(self_columns) == 1
+                            and len(other.columns) == 1
+                            and self_columns.equals(other.columns)
+                        ):
+                            shape_hint = "column"
                     return query_compiler.__constructor__(
                         query_compiler._modin_frame.broadcast_apply(
                             axis,
@@ -216,7 +230,8 @@ def caller(
                             join_type=join_type,
                             labels=labels,
                             dtypes=dtypes,
-                        )
+                        ),
+                        shape_hint=shape_hint,
                     )
                 else:
                     if (
@@ -230,13 +245,24 @@ def caller(
                         elif infer_dtypes == "float":
                             dtypes = compute_dtypes_common_cast(query_compiler, other)
                             dtypes = dtypes.apply(coerce_int_to_float64)
+                    if (
+                        self_columns is not None
+                        and other._modin_frame._columns_cache is not None
+                    ):
+                        if (
+                            len(self_columns) == 1
+                            and len(other.columns) == 1
+                            and query_compiler.columns.equals(other.columns)
+                        ):
+                            shape_hint = "column"
                     return query_compiler.__constructor__(
                         query_compiler._modin_frame.n_ary_op(
                             lambda x, y: func(x, y, *args, **kwargs),
                             [other._modin_frame],
                             join_type=join_type,
                             dtypes=dtypes,
-                        )
+                        ),
+                        shape_hint=shape_hint,
                     )
             else:
                 # TODO: it's possible to chunk the `other` and broadcast them to partitions
@@ -250,10 +276,18 @@ def caller(
                         dtypes=dtypes,
                     )
                 else:
+                    if (
+                        self_columns is not None
+                        and len(self_columns) == 1
+                        and is_scalar(other)
+                    ):
+                        shape_hint = "column"
                     new_modin_frame = query_compiler._modin_frame.map(
                         lambda df: func(df, other, *args, **kwargs),
                         dtypes=dtypes,
                     )
-                return query_compiler.__constructor__(new_modin_frame)
+                return query_compiler.__constructor__(
+                    new_modin_frame, shape_hint=shape_hint
+                )
 
         return caller


Test patch: