Repository: modin-project/modin

Issue:
QueryCompiler throws IndexError when doing a binary operation after transpose
<!--
General questions should be asked on the mailing list modin-dev@googlegroups.com.

Before submitting an issue, please fill out the following form.
-->

### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: OSX
- **Modin installed from (source or binary)**: source
- **Modin version**: source
- **Python version**: 3.6
- **Exact command to reproduce**: `df.isna().sum() / len(df)`

<!--
You can obtain the Modin version with

python -c "import modin; print(modin.__version__)"
-->

### Describe the problem
After a transpose in the query compiler, the compute kernel is not correctly propagating that transpose to the workers. This results in an index mismatch, among other errors.
<!-- Describe the problem clearly here. -->

### Source code / logs
```python
import modin.pandas as pd
df = pd.read_csv("file.csv")
df.isna().sum() / len(df)
```
<!-- Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached. Try to provide a reproducible test case that is the bare minimum necessary to generate the problem. -->



Discussion:

Resolving patch:
diff --git a/modin/backends/pandas/query_compiler.py b/modin/backends/pandas/query_compiler.py
--- a/modin/backends/pandas/query_compiler.py
+++ b/modin/backends/pandas/query_compiler.py
@@ -720,10 +720,12 @@ def list_like_op(df):
                     df.columns = new_index
                 return func(df)
 
-            new_data = self._map_across_full_axis(axis, list_like_op)
+            new_data = self._map_across_full_axis(
+                axis, self._prepare_method(list_like_op)
+            )
             return self.__constructor__(new_data, self.index, self.columns)
         else:
-            return self._map_partitions(func)
+            return self._map_partitions(self._prepare_method(func))
 
     # END Single Manager scalar operations
 


Test patch:
diff --git a/modin/pandas/test/test_dataframe.py b/modin/pandas/test/test_dataframe.py
--- a/modin/pandas/test/test_dataframe.py
+++ b/modin/pandas/test/test_dataframe.py
@@ -58,6 +58,7 @@
 class TestDFPartOne:
     # Test inter df math functions
     def inter_df_math_helper(self, modin_df, pandas_df, op):
+        # Test dataframe to datframe
         try:
             pandas_result = getattr(pandas_df, op)(pandas_df)
         except Exception as e:
@@ -67,6 +68,7 @@ def inter_df_math_helper(self, modin_df, pandas_df, op):
             modin_result = getattr(modin_df, op)(modin_df)
             df_equals(modin_result, pandas_result)
 
+        # Test dataframe to int
         try:
             pandas_result = getattr(pandas_df, op)(4)
         except Exception as e:
@@ -76,6 +78,7 @@ def inter_df_math_helper(self, modin_df, pandas_df, op):
             modin_result = getattr(modin_df, op)(4)
             df_equals(modin_result, pandas_result)
 
+        # Test dataframe to float
         try:
             pandas_result = getattr(pandas_df, op)(4.0)
         except Exception as e:
@@ -85,6 +88,16 @@ def inter_df_math_helper(self, modin_df, pandas_df, op):
             modin_result = getattr(modin_df, op)(4.0)
             df_equals(modin_result, pandas_result)
 
+        # Test transposed dataframes to float
+        try:
+            pandas_result = getattr(pandas_df.T, op)(4.0)
+        except Exception as e:
+            with pytest.raises(type(e)):
+                getattr(modin_df.T, op)(4.0)
+        else:
+            modin_result = getattr(modin_df.T, op)(4.0)
+            df_equals(modin_result, pandas_result)
+
         frame_data = {
             "{}_other".format(modin_df.columns[0]): [0, 2],
             modin_df.columns[0]: [0, 19],
@@ -93,6 +106,7 @@ def inter_df_math_helper(self, modin_df, pandas_df, op):
         modin_df2 = pd.DataFrame(frame_data)
         pandas_df2 = pandas.DataFrame(frame_data)
 
+        # Test dataframe to different dataframe shape
         try:
             pandas_result = getattr(pandas_df, op)(pandas_df2)
         except Exception as e:
@@ -102,6 +116,7 @@ def inter_df_math_helper(self, modin_df, pandas_df, op):
             modin_result = getattr(modin_df, op)(modin_df2)
             df_equals(modin_result, pandas_result)
 
+        # Test dataframe to list
         list_test = random_state.randint(RAND_LOW, RAND_HIGH, size=(modin_df.shape[1]))
         try:
             pandas_result = getattr(pandas_df, op)(list_test, axis=1)
@@ -112,6 +127,7 @@ def inter_df_math_helper(self, modin_df, pandas_df, op):
             modin_result = getattr(modin_df, op)(list_test, axis=1)
             df_equals(modin_result, pandas_result)
 
+        # Test dataframe to series
         series_test_modin = modin_df[modin_df.columns[0]]
         series_test_pandas = pandas_df[pandas_df.columns[0]]
         try:
@@ -4557,6 +4573,7 @@ def test_transpose(self, data):
 
         df_equals(modin_df.T, pandas_df.T)
         df_equals(modin_df.transpose(), pandas_df.transpose())
+
         # Uncomment below once #165 is merged
         # Test for map across full axis for select indices
         # df_equals(modin_df.T.dropna(), pandas_df.T.dropna())