Repository: modin-project/modin

Issue:
`numeric_only=True` ignored for sum, prod, min, max
### Describe the problem
This issue is a regression originating in #522. `numeric_only=True` is ignored with numeric operations. 
<!-- Describe the problem clearly here. -->

### Source code / logs
```python
import modin.pandas as pd
pd.DataFrame({"col1":list("ABCD"), "col2":[1,2,3,4], "col3":[3,4,5,6]}).sum(numeric_only=True)
```
<!-- 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/pandas/base.py b/modin/pandas/base.py
--- a/modin/pandas/base.py
+++ b/modin/pandas/base.py
@@ -1508,10 +1508,9 @@ def max(self, axis=None, skipna=None, level=None, numeric_only=None, **kwargs):
             The max of the DataFrame.
         """
         axis = self._get_axis_number(axis) if axis is not None else 0
-        self._validate_dtypes_min_max(axis, numeric_only)
-
-        return self._reduce_dimension(
-            self._query_compiler.max(
+        data = self._validate_dtypes_min_max(axis, numeric_only)
+        return data._reduce_dimension(
+            data._query_compiler.max(
                 axis=axis,
                 skipna=skipna,
                 level=level,
@@ -1531,9 +1530,11 @@ def mean(self, axis=None, skipna=None, level=None, numeric_only=None, **kwargs):
             The mean of the DataFrame. (Pandas series)
         """
         axis = self._get_axis_number(axis) if axis is not None else 0
-        self._validate_dtypes_sum_prod_mean(axis, numeric_only, ignore_axis=False)
-        return self._reduce_dimension(
-            self._query_compiler.mean(
+        data = self._validate_dtypes_sum_prod_mean(
+            axis, numeric_only, ignore_axis=False
+        )
+        return data._reduce_dimension(
+            data._query_compiler.mean(
                 axis=axis,
                 skipna=skipna,
                 level=level,
@@ -1555,7 +1556,6 @@ def median(self, axis=None, skipna=None, level=None, numeric_only=None, **kwargs
         axis = self._get_axis_number(axis) if axis is not None else 0
         if numeric_only is not None and not numeric_only:
             self._validate_dtypes(numeric_only=True)
-
         return self._reduce_dimension(
             self._query_compiler.median(
                 axis=axis,
@@ -1596,10 +1596,9 @@ def min(self, axis=None, skipna=None, level=None, numeric_only=None, **kwargs):
             The min of the DataFrame.
         """
         axis = self._get_axis_number(axis) if axis is not None else 0
-        self._validate_dtypes_min_max(axis, numeric_only)
-
-        return self._reduce_dimension(
-            self._query_compiler.min(
+        data = self._validate_dtypes_min_max(axis, numeric_only)
+        return data._reduce_dimension(
+            data._query_compiler.min(
                 axis=axis,
                 skipna=skipna,
                 level=level,
@@ -1774,9 +1773,9 @@ def prod(
             prod : Series or DataFrame (if level specified)
         """
         axis = self._get_axis_number(axis) if axis is not None else 0
-        self._validate_dtypes_sum_prod_mean(axis, numeric_only, ignore_axis=True)
-        return self._reduce_dimension(
-            self._query_compiler.prod(
+        data = self._validate_dtypes_sum_prod_mean(axis, numeric_only, ignore_axis=True)
+        return data._reduce_dimension(
+            data._query_compiler.prod(
                 axis=axis,
                 skipna=skipna,
                 level=level,
@@ -2489,7 +2488,6 @@ def skew(self, axis=None, skipna=None, level=None, numeric_only=None, **kwargs):
         axis = self._get_axis_number(axis) if axis is not None else 0
         if numeric_only is not None and not numeric_only:
             self._validate_dtypes(numeric_only=True)
-
         return self._reduce_dimension(
             self._query_compiler.skew(
                 axis=axis,
@@ -2632,7 +2630,6 @@ def std(
         axis = self._get_axis_number(axis) if axis is not None else 0
         if numeric_only is not None and not numeric_only:
             self._validate_dtypes(numeric_only=True)
-
         return self._reduce_dimension(
             self._query_compiler.std(
                 axis=axis,
@@ -2681,9 +2678,11 @@ def sum(
             The sum of the DataFrame.
         """
         axis = self._get_axis_number(axis) if axis is not None else 0
-        self._validate_dtypes_sum_prod_mean(axis, numeric_only, ignore_axis=False)
-        return self._reduce_dimension(
-            self._query_compiler.sum(
+        data = self._validate_dtypes_sum_prod_mean(
+            axis, numeric_only, ignore_axis=False
+        )
+        return data._reduce_dimension(
+            data._query_compiler.sum(
                 axis=axis,
                 skipna=skipna,
                 level=level,
@@ -3082,7 +3081,6 @@ def var(
         axis = self._get_axis_number(axis) if axis is not None else 0
         if numeric_only is not None and not numeric_only:
             self._validate_dtypes(numeric_only=True)
-
         return self._reduce_dimension(
             self._query_compiler.var(
                 axis=axis,
diff --git a/modin/pandas/dataframe.py b/modin/pandas/dataframe.py
--- a/modin/pandas/dataframe.py
+++ b/modin/pandas/dataframe.py
@@ -2115,6 +2115,16 @@ def _validate_dtypes_min_max(self, axis, numeric_only):
                 for dtype in self.dtypes
             ):
                 raise TypeError("Cannot compare Numeric and Non-Numeric Types")
+        # Pandas ignores `numeric_only` if `axis` is 1, but we do have to drop
+        # non-numeric columns if `axis` is 0.
+        if numeric_only and axis == 0:
+            return self.drop(
+                columns=[
+                    i for i in self.dtypes.index if not is_numeric_dtype(self.dtypes[i])
+                ]
+            )
+        else:
+            return self
 
     def _validate_dtypes_sum_prod_mean(self, axis, numeric_only, ignore_axis=False):
         """Raises TypeErrors for sum, prod, and mean where necessary"""
@@ -2147,6 +2157,16 @@ def _validate_dtypes_sum_prod_mean(self, axis, numeric_only, ignore_axis=False):
                 for dtype in self.dtypes
             ):
                 raise TypeError("Cannot operate on Numeric and Non-Numeric Types")
+        # Pandas ignores `numeric_only` if `axis` is 1, but we do have to drop
+        # non-numeric columns if `axis` is 0.
+        if numeric_only and axis == 0:
+            return self.drop(
+                columns=[
+                    i for i in self.dtypes.index if not is_numeric_dtype(self.dtypes[i])
+                ]
+            )
+        else:
+            return self
 
     def _to_pandas(self):
         return self._query_compiler.to_pandas()
diff --git a/modin/pandas/series.py b/modin/pandas/series.py
--- a/modin/pandas/series.py
+++ b/modin/pandas/series.py
@@ -73,10 +73,10 @@ def _reduce_dimension(self, query_compiler):
         return query_compiler.to_pandas().squeeze()
 
     def _validate_dtypes_sum_prod_mean(self, axis, numeric_only, ignore_axis=False):
-        pass
+        return self
 
     def _validate_dtypes_min_max(self, axis, numeric_only):
-        pass
+        return self
 
     def _validate_dtypes(self, numeric_only=False):
         pass


Test patch: