Repository: modin-project/modin

Issue:
default_to_pandas at groupby works incorrect when 'by' is str
### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**:  Windows 10 1809
- **Modin version** (`modin.__version__`):  0.7.3+41.gd617985
- **Python version**:  Python 3.7.5
- **Code we can use to reproduce**:
```python
if __name__ == "__main__":
    import pandas
    import modin.pandas as pd
    from modin.pandas.test.utils import df_equals

    data = {
        "col1": [0, 1, 2, 3],
        "col2": [4, 5, 6, 7],
    }

    md_grp, pd_grp = pd.DataFrame(data).groupby(by="col1"), pandas.DataFrame(data).groupby(by="col1")
    df_equals(md_grp.first(), pd_grp.first())

```
<!--
You can obtain the Modin version with

python -c "import modin; print(modin.__version__)"
-->

### Describe the problem
<!-- Describe the problem clearly here. -->
When passing `by` parameter as str, modin groupby behaves differ from pandas. It works like if we pass to the `by` column itself, not just its name. The problem occurs only with those operations that falls to `_default_to_pandas`.
### Source code / logs
<!-- 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. -->
Well, to start with that pandas itself behaves differently when we pass column to the `by` and its name:
```python
import pandas
data = {
    "col1": [0, 1, 2, 3],
    "col2": [4, 5, 6, 7],
}

df = pandas.DataFrame(data)
col1 = df["col1"].copy()

grp1, grp2 = df.groupby(col1), df.groupby(col1.name)
pandas.testing.assert_frame_equal(grp1.first(), grp2.first())
```
related code will output:
```
AssertionError: DataFrame are different

DataFrame shape mismatch
[left]:  (4, 2)
[right]: (4, 1)
```

So it's important to keep type of what we are grouping, but as we see at [dataframe.py: def groupby()](https://github.com/modin-project/modin/blob/master/modin/pandas/dataframe.py#L405-L416):
```python
...
elif isinstance(by, str):
    drop = by in self.columns
    idx_name = by
    if (
        isinstance(self.axes[axis], pandas.MultiIndex)
        and by in self.axes[axis].names
     ):
        pass
     else:
        by = self.__getitem__(by)._query_compiler
...
```
we set `by` to the column value, and then, at [groupby.py: def _default_to_pandas()](https://github.com/modin-project/modin/blob/master/modin/pandas/groupby.py#L571-L593) we have no ability to track the origin type of `by`



Discussion:

Resolving patch:
diff --git a/modin/pandas/dataframe.py b/modin/pandas/dataframe.py
--- a/modin/pandas/dataframe.py
+++ b/modin/pandas/dataframe.py
@@ -400,6 +400,14 @@ def groupby(
         # strings is passed in, the data used for the groupby is dropped before the
         # groupby takes place.
         drop = False
+
+        if (
+            not isinstance(by, (pandas.Series, Series))
+            and is_list_like(by)
+            and len(by) == 1
+        ):
+            by = by[0]
+
         if callable(by):
             by = self.index.map(by)
         elif isinstance(by, str):
diff --git a/modin/pandas/groupby.py b/modin/pandas/groupby.py
--- a/modin/pandas/groupby.py
+++ b/modin/pandas/groupby.py
@@ -581,7 +581,7 @@ def _default_to_pandas(self, f, **kwargs):
             isinstance(self._by, type(self._query_compiler))
             and len(self._by.columns) == 1
         ):
-            by = self._by.to_pandas().squeeze()
+            by = self._by.columns[0] if self._drop else self._by.to_pandas().squeeze()
         elif isinstance(self._by, type(self._query_compiler)):
             by = list(self._by.columns)
         else:


Test patch:
diff --git a/modin/pandas/test/test_groupby.py b/modin/pandas/test/test_groupby.py
--- a/modin/pandas/test/test_groupby.py
+++ b/modin/pandas/test/test_groupby.py
@@ -37,6 +37,27 @@ def modin_groupby_equals_pandas(modin_groupby, pandas_groupby):
         df_equals(g1[1], g2[1])
 
 
+def eval_general(
+    modin_groupby, pandas_groupby, fn, comparator=df_equals, is_default=False
+):
+    try:
+        pandas_result = fn(pandas_groupby)
+    except Exception as e:
+        with pytest.raises(type(e)):
+            if is_default:
+                with pytest.warns(UserWarning):
+                    fn(modin_groupby)
+            else:
+                fn(modin_groupby)
+    else:
+        if is_default:
+            with pytest.warns(UserWarning):
+                modin_result = fn(modin_groupby)
+        else:
+            modin_result = fn(modin_groupby)
+        comparator(modin_result, pandas_result)
+
+
 @pytest.mark.parametrize("as_index", [True, False])
 def test_mixed_dtypes_groupby(as_index):
     frame_data = np.random.randint(97, 198, size=(2 ** 6, 2 ** 4))
@@ -62,15 +83,31 @@ def test_mixed_dtypes_groupby(as_index):
 
         modin_groupby_equals_pandas(modin_groupby, pandas_groupby)
         eval_ngroups(modin_groupby, pandas_groupby)
-        eval_ffill(modin_groupby, pandas_groupby)
-        eval_sem(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.ffill(), is_default=True
+        )
+        eval_general(
+            modin_groupby,
+            pandas_groupby,
+            lambda df: df.sem(),
+            modin_df_almost_equals_pandas,
+            is_default=True,
+        )
         eval_mean(modin_groupby, pandas_groupby)
         eval_any(modin_groupby, pandas_groupby)
         eval_min(modin_groupby, pandas_groupby)
-        eval_idxmax(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.idxmax(), is_default=True
+        )
         eval_ndim(modin_groupby, pandas_groupby)
         eval_cumsum(modin_groupby, pandas_groupby)
-        eval_pct_change(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby,
+            pandas_groupby,
+            lambda df: df.pct_change(),
+            modin_df_almost_equals_pandas,
+            is_default=True,
+        )
         eval_cummax(modin_groupby, pandas_groupby)
 
         # TODO Add more apply functions
@@ -79,11 +116,19 @@ def test_mixed_dtypes_groupby(as_index):
             eval_apply(modin_groupby, pandas_groupby, func)
 
         eval_dtypes(modin_groupby, pandas_groupby)
-        eval_first(modin_groupby, pandas_groupby)
-        eval_backfill(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.first(), is_default=True
+        )
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.backfill(), is_default=True
+        )
         eval_cummin(modin_groupby, pandas_groupby)
-        eval_bfill(modin_groupby, pandas_groupby)
-        eval_idxmin(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.bfill(), is_default=True
+        )
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.idxmin(), is_default=True
+        )
         eval_prod(modin_groupby, pandas_groupby)
         if as_index:
             eval_std(modin_groupby, pandas_groupby)
@@ -95,17 +140,33 @@ def test_mixed_dtypes_groupby(as_index):
             eval_agg(modin_groupby, pandas_groupby, func)
             eval_aggregate(modin_groupby, pandas_groupby, func)
 
-        eval_last(modin_groupby, pandas_groupby)
-        eval_mad(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.last(), is_default=True
+        )
+        eval_general(
+            modin_groupby,
+            pandas_groupby,
+            lambda df: df.mad(),
+            modin_df_almost_equals_pandas,
+            is_default=True,
+        )
         eval_max(modin_groupby, pandas_groupby)
         eval_len(modin_groupby, pandas_groupby)
         eval_sum(modin_groupby, pandas_groupby)
         eval_ngroup(modin_groupby, pandas_groupby)
         eval_nunique(modin_groupby, pandas_groupby)
         eval_median(modin_groupby, pandas_groupby)
-        eval_head(modin_groupby, pandas_groupby, n)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.head(n), is_default=True
+        )
         eval_cumprod(modin_groupby, pandas_groupby)
-        eval_cov(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby,
+            pandas_groupby,
+            lambda df: df.cov(),
+            modin_df_almost_equals_pandas,
+            is_default=True,
+        )
 
         transform_functions = [lambda df: df, lambda df: df + df]
         for func in transform_functions:
@@ -115,18 +176,27 @@ def test_mixed_dtypes_groupby(as_index):
         for func in pipe_functions:
             eval_pipe(modin_groupby, pandas_groupby, func)
 
-        eval_corr(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby,
+            pandas_groupby,
+            lambda df: df.corr(),
+            modin_df_almost_equals_pandas,
+        )
         eval_fillna(modin_groupby, pandas_groupby)
         eval_count(modin_groupby, pandas_groupby)
-        eval_tail(modin_groupby, pandas_groupby, n)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.tail(n), is_default=True
+        )
         eval_quantile(modin_groupby, pandas_groupby)
-        eval_take(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.take(), is_default=True
+        )
         eval___getattr__(modin_groupby, pandas_groupby, "col2")
         eval_groups(modin_groupby, pandas_groupby)
 
 
 @pytest.mark.parametrize(
-    "by", [[1, 2, 1, 2], lambda x: x % 3, "col1", ["col1", "col2"]]
+    "by", [[1, 2, 1, 2], lambda x: x % 3, "col1", ["col1"], ["col1", "col2"]]
 )
 @pytest.mark.parametrize("as_index", [True, False])
 def test_simple_row_groupby(by, as_index):
@@ -147,15 +217,27 @@ def test_simple_row_groupby(by, as_index):
 
     modin_groupby_equals_pandas(modin_groupby, pandas_groupby)
     eval_ngroups(modin_groupby, pandas_groupby)
-    eval_ffill(modin_groupby, pandas_groupby)
-    eval_sem(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.ffill(), is_default=True)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.sem(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_mean(modin_groupby, pandas_groupby)
     eval_any(modin_groupby, pandas_groupby)
     eval_min(modin_groupby, pandas_groupby)
-    eval_idxmax(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.idxmax(), is_default=True)
     eval_ndim(modin_groupby, pandas_groupby)
     eval_cumsum(modin_groupby, pandas_groupby)
-    eval_pct_change(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.pct_change(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_cummax(modin_groupby, pandas_groupby)
 
     # pandas is inconsistent between test environment and here, more investigation is
@@ -167,11 +249,13 @@ def test_simple_row_groupby(by, as_index):
             eval_apply(modin_groupby, pandas_groupby, func)
 
     eval_dtypes(modin_groupby, pandas_groupby)
-    eval_first(modin_groupby, pandas_groupby)
-    eval_backfill(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.first(), is_default=True)
+    eval_general(
+        modin_groupby, pandas_groupby, lambda df: df.backfill(), is_default=True
+    )
     eval_cummin(modin_groupby, pandas_groupby)
-    eval_bfill(modin_groupby, pandas_groupby)
-    eval_idxmin(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.bfill(), is_default=True)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.idxmin(), is_default=True)
     eval_prod(modin_groupby, pandas_groupby)
     if as_index:
         eval_std(modin_groupby, pandas_groupby)
@@ -183,8 +267,14 @@ def test_simple_row_groupby(by, as_index):
         eval_agg(modin_groupby, pandas_groupby, func)
         eval_aggregate(modin_groupby, pandas_groupby, func)
 
-    eval_last(modin_groupby, pandas_groupby)
-    eval_mad(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.last(), is_default=True)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.mad(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_rank(modin_groupby, pandas_groupby)
     eval_max(modin_groupby, pandas_groupby)
     eval_len(modin_groupby, pandas_groupby)
@@ -192,9 +282,15 @@ def test_simple_row_groupby(by, as_index):
     eval_ngroup(modin_groupby, pandas_groupby)
     eval_nunique(modin_groupby, pandas_groupby)
     eval_median(modin_groupby, pandas_groupby)
-    eval_head(modin_groupby, pandas_groupby, n)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.head(n), is_default=True)
     eval_cumprod(modin_groupby, pandas_groupby)
-    eval_cov(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.cov(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
 
     transform_functions = [lambda df: df + 4, lambda df: -df - 10]
     for func in transform_functions:
@@ -204,12 +300,18 @@ def test_simple_row_groupby(by, as_index):
     for func in pipe_functions:
         eval_pipe(modin_groupby, pandas_groupby, func)
 
-    eval_corr(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.corr(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_fillna(modin_groupby, pandas_groupby)
     eval_count(modin_groupby, pandas_groupby)
-    eval_tail(modin_groupby, pandas_groupby, n)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.tail(n), is_default=True)
     eval_quantile(modin_groupby, pandas_groupby)
-    eval_take(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.take(), is_default=True)
     eval___getattr__(modin_groupby, pandas_groupby, "col3")
     eval_groups(modin_groupby, pandas_groupby)
 
@@ -236,15 +338,27 @@ def test_single_group_row_groupby():
     modin_groupby_equals_pandas(modin_groupby, pandas_groupby)
     eval_ngroups(modin_groupby, pandas_groupby)
     eval_skew(modin_groupby, pandas_groupby)
-    eval_ffill(modin_groupby, pandas_groupby)
-    eval_sem(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.ffill(), is_default=True)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.sem(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_mean(modin_groupby, pandas_groupby)
     eval_any(modin_groupby, pandas_groupby)
     eval_min(modin_groupby, pandas_groupby)
-    eval_idxmax(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.idxmax(), is_default=True)
     eval_ndim(modin_groupby, pandas_groupby)
     eval_cumsum(modin_groupby, pandas_groupby)
-    eval_pct_change(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.pct_change(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_cummax(modin_groupby, pandas_groupby)
 
     apply_functions = [lambda df: df.sum(), lambda df: -df]
@@ -252,11 +366,13 @@ def test_single_group_row_groupby():
         eval_apply(modin_groupby, pandas_groupby, func)
 
     eval_dtypes(modin_groupby, pandas_groupby)
-    eval_first(modin_groupby, pandas_groupby)
-    eval_backfill(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.first(), is_default=True)
+    eval_general(
+        modin_groupby, pandas_groupby, lambda df: df.backfill(), is_default=True
+    )
     eval_cummin(modin_groupby, pandas_groupby)
-    eval_bfill(modin_groupby, pandas_groupby)
-    eval_idxmin(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.bfill(), is_default=True)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.idxmin(), is_default=True)
     eval_prod(modin_groupby, pandas_groupby)
     eval_std(modin_groupby, pandas_groupby)
 
@@ -265,8 +381,14 @@ def test_single_group_row_groupby():
         eval_agg(modin_groupby, pandas_groupby, func)
         eval_aggregate(modin_groupby, pandas_groupby, func)
 
-    eval_last(modin_groupby, pandas_groupby)
-    eval_mad(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.last(), is_default=True)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.mad(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_rank(modin_groupby, pandas_groupby)
     eval_max(modin_groupby, pandas_groupby)
     eval_var(modin_groupby, pandas_groupby)
@@ -275,9 +397,15 @@ def test_single_group_row_groupby():
     eval_ngroup(modin_groupby, pandas_groupby)
     eval_nunique(modin_groupby, pandas_groupby)
     eval_median(modin_groupby, pandas_groupby)
-    eval_head(modin_groupby, pandas_groupby, n)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.head(n), is_default=True)
     eval_cumprod(modin_groupby, pandas_groupby)
-    eval_cov(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.cov(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
 
     transform_functions = [lambda df: df + 4, lambda df: -df - 10]
     for func in transform_functions:
@@ -287,12 +415,18 @@ def test_single_group_row_groupby():
     for func in pipe_functions:
         eval_pipe(modin_groupby, pandas_groupby, func)
 
-    eval_corr(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.corr(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_fillna(modin_groupby, pandas_groupby)
     eval_count(modin_groupby, pandas_groupby)
-    eval_tail(modin_groupby, pandas_groupby, n)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.tail(n), is_default=True)
     eval_quantile(modin_groupby, pandas_groupby)
-    eval_take(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.take(), is_default=True)
     eval___getattr__(modin_groupby, pandas_groupby, "col2")
     eval_groups(modin_groupby, pandas_groupby)
 
@@ -313,15 +447,27 @@ def test_large_row_groupby():
     modin_groupby_equals_pandas(modin_groupby, pandas_groupby)
     eval_ngroups(modin_groupby, pandas_groupby)
     eval_skew(modin_groupby, pandas_groupby)
-    eval_ffill(modin_groupby, pandas_groupby)
-    eval_sem(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.ffill(), is_default=True)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.sem(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_mean(modin_groupby, pandas_groupby)
     eval_any(modin_groupby, pandas_groupby)
     eval_min(modin_groupby, pandas_groupby)
-    eval_idxmax(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.idxmax(), is_default=True)
     eval_ndim(modin_groupby, pandas_groupby)
     eval_cumsum(modin_groupby, pandas_groupby)
-    eval_pct_change(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.pct_change(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_cummax(modin_groupby, pandas_groupby)
 
     apply_functions = [lambda df: df.sum(), lambda df: -df]
@@ -329,11 +475,13 @@ def test_large_row_groupby():
         eval_apply(modin_groupby, pandas_groupby, func)
 
     eval_dtypes(modin_groupby, pandas_groupby)
-    eval_first(modin_groupby, pandas_groupby)
-    eval_backfill(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.first(), is_default=True)
+    eval_general(
+        modin_groupby, pandas_groupby, lambda df: df.backfill(), is_default=True
+    )
     eval_cummin(modin_groupby, pandas_groupby)
-    eval_bfill(modin_groupby, pandas_groupby)
-    eval_idxmin(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.bfill(), is_default=True)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.idxmin(), is_default=True)
     # eval_prod(modin_groupby, pandas_groupby) causes overflows
     eval_std(modin_groupby, pandas_groupby)
 
@@ -342,8 +490,14 @@ def test_large_row_groupby():
         eval_agg(modin_groupby, pandas_groupby, func)
         eval_aggregate(modin_groupby, pandas_groupby, func)
 
-    eval_last(modin_groupby, pandas_groupby)
-    eval_mad(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.last(), is_default=True)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.mad(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_rank(modin_groupby, pandas_groupby)
     eval_max(modin_groupby, pandas_groupby)
     eval_var(modin_groupby, pandas_groupby)
@@ -352,9 +506,15 @@ def test_large_row_groupby():
     eval_ngroup(modin_groupby, pandas_groupby)
     eval_nunique(modin_groupby, pandas_groupby)
     eval_median(modin_groupby, pandas_groupby)
-    eval_head(modin_groupby, pandas_groupby, n)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.head(n), is_default=True)
     # eval_cumprod(modin_groupby, pandas_groupby) causes overflows
-    eval_cov(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.cov(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
 
     transform_functions = [lambda df: df + 4, lambda df: -df - 10]
     for func in transform_functions:
@@ -364,12 +524,18 @@ def test_large_row_groupby():
     for func in pipe_functions:
         eval_pipe(modin_groupby, pandas_groupby, func)
 
-    eval_corr(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.corr(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_fillna(modin_groupby, pandas_groupby)
     eval_count(modin_groupby, pandas_groupby)
-    eval_tail(modin_groupby, pandas_groupby, n)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.tail(n), is_default=True)
     eval_quantile(modin_groupby, pandas_groupby)
-    eval_take(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.take(), is_default=True)
     eval_groups(modin_groupby, pandas_groupby)
 
 
@@ -394,15 +560,21 @@ def test_simple_col_groupby():
     modin_groupby_equals_pandas(modin_groupby, pandas_groupby)
     eval_ngroups(modin_groupby, pandas_groupby)
     eval_skew(modin_groupby, pandas_groupby)
-    eval_ffill(modin_groupby, pandas_groupby)
-    eval_sem(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.ffill(), is_default=True)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.sem(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_mean(modin_groupby, pandas_groupby)
     eval_any(modin_groupby, pandas_groupby)
     eval_min(modin_groupby, pandas_groupby)
     eval_ndim(modin_groupby, pandas_groupby)
 
-    eval_idxmax(modin_groupby, pandas_groupby)
-    eval_idxmin(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.idxmax(), is_default=True)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.idxmin(), is_default=True)
     eval_quantile(modin_groupby, pandas_groupby)
 
     # https://github.com/pandas-dev/pandas/issues/21127
@@ -411,18 +583,32 @@ def test_simple_col_groupby():
     # eval_cummin(modin_groupby, pandas_groupby)
     # eval_cumprod(modin_groupby, pandas_groupby)
 
-    eval_pct_change(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.pct_change(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     apply_functions = [lambda df: -df, lambda df: df.sum(axis=1)]
     for func in apply_functions:
         eval_apply(modin_groupby, pandas_groupby, func)
 
-    eval_first(modin_groupby, pandas_groupby)
-    eval_backfill(modin_groupby, pandas_groupby)
-    eval_bfill(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.first(), is_default=True)
+    eval_general(
+        modin_groupby, pandas_groupby, lambda df: df.backfill(), is_default=True
+    )
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.bfill(), is_default=True)
     eval_prod(modin_groupby, pandas_groupby)
     eval_std(modin_groupby, pandas_groupby)
-    eval_last(modin_groupby, pandas_groupby)
-    eval_mad(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.last(), is_default=True)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.mad(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_max(modin_groupby, pandas_groupby)
     eval_var(modin_groupby, pandas_groupby)
     eval_len(modin_groupby, pandas_groupby)
@@ -432,7 +618,13 @@ def test_simple_col_groupby():
     # eval_ngroup(modin_groupby, pandas_groupby)
     # eval_nunique(modin_groupby, pandas_groupby)
     eval_median(modin_groupby, pandas_groupby)
-    eval_cov(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.cov(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
 
     transform_functions = [lambda df: df + 4, lambda df: -df - 10]
     for func in transform_functions:
@@ -442,10 +634,16 @@ def test_simple_col_groupby():
     for func in pipe_functions:
         eval_pipe(modin_groupby, pandas_groupby, func)
 
-    eval_corr(modin_groupby, pandas_groupby)
+    eval_general(
+        modin_groupby,
+        pandas_groupby,
+        lambda df: df.corr(),
+        modin_df_almost_equals_pandas,
+        is_default=True,
+    )
     eval_fillna(modin_groupby, pandas_groupby)
     eval_count(modin_groupby, pandas_groupby)
-    eval_take(modin_groupby, pandas_groupby)
+    eval_general(modin_groupby, pandas_groupby, lambda df: df.take(), is_default=True)
     eval_groups(modin_groupby, pandas_groupby)
 
 
@@ -469,26 +667,50 @@ def test_series_groupby(by, as_index):
 
         modin_groupby_equals_pandas(modin_groupby, pandas_groupby)
         eval_ngroups(modin_groupby, pandas_groupby)
-        eval_ffill(modin_groupby, pandas_groupby)
-        eval_sem(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.ffill(), is_default=True
+        )
+        eval_general(
+            modin_groupby,
+            pandas_groupby,
+            lambda df: df.sem(),
+            modin_df_almost_equals_pandas,
+            is_default=True,
+        )
         eval_mean(modin_groupby, pandas_groupby)
         eval_any(modin_groupby, pandas_groupby)
         eval_min(modin_groupby, pandas_groupby)
-        eval_idxmax(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.idxmax(), is_default=True
+        )
         eval_ndim(modin_groupby, pandas_groupby)
         eval_cumsum(modin_groupby, pandas_groupby)
-        eval_pct_change(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby,
+            pandas_groupby,
+            lambda df: df.pct_change(),
+            modin_df_almost_equals_pandas,
+            is_default=True,
+        )
         eval_cummax(modin_groupby, pandas_groupby)
 
         apply_functions = [lambda df: df.sum(), min]
         for func in apply_functions:
             eval_apply(modin_groupby, pandas_groupby, func)
 
-        eval_first(modin_groupby, pandas_groupby)
-        eval_backfill(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.first(), is_default=True
+        )
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.backfill(), is_default=True
+        )
         eval_cummin(modin_groupby, pandas_groupby)
-        eval_bfill(modin_groupby, pandas_groupby)
-        eval_idxmin(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.bfill(), is_default=True
+        )
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.idxmin(), is_default=True
+        )
         eval_prod(modin_groupby, pandas_groupby)
         if as_index:
             eval_std(modin_groupby, pandas_groupby)
@@ -500,8 +722,16 @@ def test_series_groupby(by, as_index):
             eval_agg(modin_groupby, pandas_groupby, func)
             eval_aggregate(modin_groupby, pandas_groupby, func)
 
-        eval_last(modin_groupby, pandas_groupby)
-        eval_mad(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.last(), is_default=True
+        )
+        eval_general(
+            modin_groupby,
+            pandas_groupby,
+            lambda df: df.mad(),
+            modin_df_almost_equals_pandas,
+            is_default=True,
+        )
         eval_rank(modin_groupby, pandas_groupby)
         eval_max(modin_groupby, pandas_groupby)
         eval_len(modin_groupby, pandas_groupby)
@@ -509,7 +739,9 @@ def test_series_groupby(by, as_index):
         eval_ngroup(modin_groupby, pandas_groupby)
         eval_nunique(modin_groupby, pandas_groupby)
         eval_median(modin_groupby, pandas_groupby)
-        eval_head(modin_groupby, pandas_groupby, n)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.head(n), is_default=True
+        )
         eval_cumprod(modin_groupby, pandas_groupby)
 
         transform_functions = [lambda df: df + 4, lambda df: -df - 10]
@@ -522,9 +754,13 @@ def test_series_groupby(by, as_index):
 
         eval_fillna(modin_groupby, pandas_groupby)
         eval_count(modin_groupby, pandas_groupby)
-        eval_tail(modin_groupby, pandas_groupby, n)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.tail(n), is_default=True
+        )
         eval_quantile(modin_groupby, pandas_groupby)
-        eval_take(modin_groupby, pandas_groupby)
+        eval_general(
+            modin_groupby, pandas_groupby, lambda df: df.take(), is_default=True
+        )
         eval_groups(modin_groupby, pandas_groupby)
 
 
@@ -562,19 +798,6 @@ def eval_skew(modin_groupby, pandas_groupby):
     modin_df_almost_equals_pandas(modin_groupby.skew(), pandas_groupby.skew())
 
 
-def eval_ffill(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        try:
-            modin_groupby.ffill()
-        except Exception:
-            pass
-
-
-def eval_sem(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        modin_groupby.sem()
-
-
 def eval_mean(modin_groupby, pandas_groupby):
     modin_df_almost_equals_pandas(modin_groupby.mean(), pandas_groupby.mean())
 
@@ -587,11 +810,6 @@ def eval_min(modin_groupby, pandas_groupby):
     df_equals(modin_groupby.min(), pandas_groupby.min())
 
 
-def eval_idxmax(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        modin_groupby.idxmax()
-
-
 def eval_ndim(modin_groupby, pandas_groupby):
     assert modin_groupby.ndim == pandas_groupby.ndim
 
@@ -600,14 +818,6 @@ def eval_cumsum(modin_groupby, pandas_groupby, axis=0):
     df_equals(modin_groupby.cumsum(axis=axis), pandas_groupby.cumsum(axis=axis))
 
 
-def eval_pct_change(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        try:
-            modin_groupby.pct_change()
-        except Exception:
-            pass
-
-
 def eval_cummax(modin_groupby, pandas_groupby, axis=0):
     df_equals(modin_groupby.cummax(axis=axis), pandas_groupby.cummax(axis=axis))
 
@@ -620,36 +830,10 @@ def eval_dtypes(modin_groupby, pandas_groupby):
     df_equals(modin_groupby.dtypes, pandas_groupby.dtypes)
 
 
-def eval_first(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        modin_groupby.first()
-
-
-def eval_backfill(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        try:
-            modin_groupby.backfill()
-        except Exception:
-            pass
-
-
 def eval_cummin(modin_groupby, pandas_groupby, axis=0):
     df_equals(modin_groupby.cummin(axis=axis), pandas_groupby.cummin(axis=axis))
 
 
-def eval_bfill(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        try:
-            modin_groupby.bfill()
-        except Exception:
-            pass
-
-
-def eval_idxmin(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        modin_groupby.idxmin()
-
-
 def eval_prod(modin_groupby, pandas_groupby):
     df_equals(modin_groupby.prod(), pandas_groupby.prod())
 
@@ -666,16 +850,6 @@ def eval_agg(modin_groupby, pandas_groupby, func):
     df_equals(modin_groupby.agg(func), pandas_groupby.agg(func))
 
 
-def eval_last(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        modin_groupby.last()
-
-
-def eval_mad(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        modin_groupby.mad()
-
-
 def eval_rank(modin_groupby, pandas_groupby):
     df_equals(modin_groupby.rank(), pandas_groupby.rank())
 
@@ -708,30 +882,15 @@ def eval_median(modin_groupby, pandas_groupby):
     modin_df_almost_equals_pandas(modin_groupby.median(), pandas_groupby.median())
 
 
-def eval_head(modin_groupby, pandas_groupby, n):
-    with pytest.warns(UserWarning):
-        modin_groupby.head()
-
-
 def eval_cumprod(modin_groupby, pandas_groupby, axis=0):
     df_equals(modin_groupby.cumprod(), pandas_groupby.cumprod())
     df_equals(modin_groupby.cumprod(axis=axis), pandas_groupby.cumprod(axis=axis))
 
 
-def eval_cov(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        modin_groupby.cov()
-
-
 def eval_transform(modin_groupby, pandas_groupby, func):
     df_equals(modin_groupby.transform(func), pandas_groupby.transform(func))
 
 
-def eval_corr(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        modin_groupby.corr()
-
-
 def eval_fillna(modin_groupby, pandas_groupby):
     df_equals(
         modin_groupby.fillna(method="ffill"), pandas_groupby.fillna(method="ffill")
@@ -746,11 +905,6 @@ def eval_pipe(modin_groupby, pandas_groupby, func):
     df_equals(modin_groupby.pipe(func), pandas_groupby.pipe(func))
 
 
-def eval_tail(modin_groupby, pandas_groupby, n):
-    with pytest.warns(UserWarning):
-        modin_groupby.tail()
-
-
 def eval_quantile(modin_groupby, pandas_groupby):
     try:
         pandas_result = pandas_groupby.quantile(q=0.4)
@@ -761,14 +915,6 @@ def eval_quantile(modin_groupby, pandas_groupby):
         df_equals(modin_groupby.quantile(q=0.4), pandas_result)
 
 
-def eval_take(modin_groupby, pandas_groupby):
-    with pytest.warns(UserWarning):
-        try:
-            modin_groupby.take()
-        except Exception:
-            pass
-
-
 def eval___getattr__(modin_groupby, pandas_groupby, item):
     try:
         pandas_result = pandas_groupby[item].count()