Repository: modin-project/modin

Issue:
Mode returns wrong values
### Describe the problem
When we run `mode`, we sometimes get a dataframe that is incorrect.

### Source code / logs
```
import modin.pandas as pd
import numpy as np
import pandas

data = {"col{}".format((i-50)%100+1): np.random.randint(-100, 100, size=(100)) for i in range(100)}
modin_df = pd.DataFrame(data)
pandas_df = pandas.DataFrame(data)
```
With the above code block, `modin_df.mode()` does not equal `pandas_df`


Discussion:

Resolving patch:
diff --git a/modin/data_management/query_compiler/pandas_query_compiler.py b/modin/data_management/query_compiler/pandas_query_compiler.py
--- a/modin/data_management/query_compiler/pandas_query_compiler.py
+++ b/modin/data_management/query_compiler/pandas_query_compiler.py
@@ -1728,37 +1728,39 @@ def mode(self, **kwargs):
             A new PandasDataManager with modes calculated.
         """
         axis = kwargs.get("axis", 0)
-        numeric_only = kwargs.get("numeric_only", False)
-        func = self._prepare_method(pandas.DataFrame.mode, **kwargs)
-        new_data = self.map_across_full_axis(axis, func)
 
-        if numeric_only:
-            result, query_compiler = self.numeric_function_clean_dataframe(axis)
-            if result is not None:
-                return self.from_pandas(
-                    pandas.DataFrame(index=query_compiler.index), type(self.data)
+        def mode_builder(df, **kwargs):
+            result = df.mode(**kwargs)
+            # We return a dataframe with the same shape as the input to ensure
+            # that all the partitions will be the same shape
+            if not axis and len(df) != len(result):
+                # Pad columns
+                append_values = pandas.DataFrame(
+                    columns=result.columns, index=range(len(result), len(df))
                 )
-        else:
-            query_compiler = self
-
-        max_count = (
-            self.__constructor__(new_data, query_compiler.index, query_compiler.columns)
-            .notnull()
-            .sum(axis=axis)
-        ).max()
+                result = pandas.concat([result, append_values], ignore_index=True)
+            elif axis:
+                # Pad rows
+                append_vals = pandas.DataFrame(
+                    columns=range(len(result.columns), len(df)), index=result.index
+                )
+                result = pandas.concat([result, append_vals], axis=1)
+            return result
 
-        new_index = pandas.RangeIndex(max_count) if not axis else query_compiler.index
-        new_columns = (
-            query_compiler.columns if not axis else pandas.RangeIndex(max_count)
-        )
+        func = self._prepare_method(mode_builder, **kwargs)
+        new_data = self.map_across_full_axis(axis, func)
+        new_index = pandas.RangeIndex(len(self.index)) if not axis else self.index
+        new_columns = self.columns if not axis else pandas.RangeIndex(len(self.columns))
         # We have to reindex the DataFrame so that all of the partitions are
         # matching in shape. The next steps ensure this happens.
         final_labels = new_index if not axis else new_columns
         # We build these intermediate objects to avoid depending directly on
         # the underlying implementation.
-        return self.__constructor__(
-            new_data, new_index, new_columns, query_compiler._dtype_cache
-        ).reindex(axis=axis, labels=final_labels)
+        return (
+            self.__constructor__(new_data, new_index, new_columns, self._dtype_cache)
+            .reindex(axis=axis, labels=final_labels)
+            .dropna(axis=axis, how="all")
+        )
 
     def fillna(self, **kwargs):
         """Replaces NaN values with the method provided.


Test patch: