Repository: pandas-dev/pandas
Pull request: TST : add test for groupby aggregation dtype
- [ ] closes #32793
- [ ] tests added / passed
- [ ] Ensure all linting tests pass, see [here](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit) for how to run them
- [ ] whatsnew entry


Problem statement:
Aggregation does not preserve dtype when function passed in dictionary
#### Code Sample, a copy-pastable example if possible

```python
In [92]: df_ = pd.DataFrame([[0, 1], [0, np.nan]]).convert_dtypes()

In [93]: df_
Out[93]: 
   0     1
0  0     1
1  0  <NA>

In [108]: df_.groupby(0).agg('last')
Out[111]: 
   1
0   
0  1

In [112]: df_.groupby(0).agg({1:'last'})
Out[115]: 
     1
0     
0  1.0


In [116]: df_.groupby(0).agg('last').dtypes
Out[116]: 
1    Int64
dtype: object

In [117]: df_.groupby(0).agg({1:'last'}).dtypes
Out[117]: 
1    float64
dtype: object

```
#### Problem description
Aggregation does not preserve Int64 dtype when function passed in dictionary for the column.

#### Expected Output
Int64 dtype 
#### Output of ``pd.show_versions()``

<details>

INSTALLED VERSIONS
------------------
commit           : None
python           : 3.7.5.final.0
python-bits      : 64
OS               : Linux
OS-release       : 5.5.8-100.fc30.x86_64
machine          : x86_64
processor        : x86_64
byteorder        : little
LC_ALL           : None
LANG             : nb_NO.UTF-8
LOCALE           : nb_NO.UTF-8

pandas           : 1.0.2
numpy            : 1.18.1
pytz             : 2019.3
dateutil         : 2.8.1
pip              : 19.3.1
setuptools       : 41.6.0.post20191030
Cython           : 0.29.13
pytest           : 5.2.2
hypothesis       : None
sphinx           : 2.2.1
blosc            : None
feather          : None
xlsxwriter       : 1.2.2
lxml.etree       : 4.4.1
html5lib         : 1.0.1
pymysql          : None
psycopg2         : 2.8.4 (dt dec pq3 ext lo64)
jinja2           : 2.10.3
IPython          : 7.9.0
pandas_datareader: None
bs4              : 4.8.1
bottleneck       : 1.2.1
fastparquet      : None
gcsfs            : None
lxml.etree       : 4.4.1
matplotlib       : 2.2.3
numexpr          : 2.7.0
odfpy            : None
openpyxl         : 3.0.0
pandas_gbq       : None
pyarrow          : 0.16.0
pytables         : None
pytest           : 5.2.2
pyxlsb           : None
s3fs             : None
scipy            : 1.3.1
sqlalchemy       : 1.3.10
tables           : 3.5.2
tabulate         : 0.8.5
xarray           : None
xlrd             : 1.2.0
xlwt             : 1.3.0
xlsxwriter       : 1.2.2
numba            : 0.46.0

</details>

Hints from issue discussion:
Looks to work on master now. Could use a test

```
In [1]: In [92]: df_ = pd.DataFrame([[0, 1], [0, np.nan]]).convert_dtypes()
   ...:
   ...: In [93]: df_
Out[1]:
   0     1
0  0     1
1  0  <NA>

In [2]: In [108]: df_.groupby(0).agg('last')
Out[2]:
   1
0
0  1

In [3]: In [112]: df_.groupby(0).agg({1:'last'})
Out[3]:
   1
0
0  1

In [4]: In [116]: df_.groupby(0).agg('last').dtypes
Out[4]:
1    Int64
dtype: object

In [5]: In [117]: df_.groupby(0).agg({1:'last'}).dtypes
Out[5]:
1    Int64
dtype: object
```

Commit message: add reduction_func parameter

Patch to review:
diff --git a/pandas/tests/groupby/aggregate/test_aggregate.py b/pandas/tests/groupby/aggregate/test_aggregate.py
index 2c798e543bf6b..d79889a94ba88 100644
--- a/pandas/tests/groupby/aggregate/test_aggregate.py
+++ b/pandas/tests/groupby/aggregate/test_aggregate.py
@@ -1327,6 +1327,23 @@ def func(ser):
     tm.assert_frame_equal(res, expected)
 
 
+def test_groupby_aggregate_directory(reduction_func):
+    # GH#32793
+    if reduction_func not in ["corrwith", "nth"]:
+        obj = DataFrame([[0, 1], [0, np.nan]])
+
+        obj.convert_dtypes()
+        df_agg_last = obj.groupby(0).agg(reduction_func)
+        df_agg_last_dir = obj.groupby(0).agg({1: reduction_func})
+
+        if reduction_func in ["size", "ngroup"]:
+            tm.assert_equal(df_agg_last.values, df_agg_last_dir[1].values)
+            assert df_agg_last.dtypes == df_agg_last_dir[1].dtypes
+        else:
+            tm.assert_frame_equal(df_agg_last, df_agg_last_dir)
+            tm.assert_series_equal(df_agg_last.dtypes, df_agg_last_dir.dtypes)
+
+
 def test_group_mean_timedelta_nat():
     # GH43132
     data = Series(["1 day", "3 days", "NaT"], dtype="timedelta64[ns]")


Code review comments:
diff_hunk: @@ -1327,6 +1327,23 @@ def func(ser):
     tm.assert_frame_equal(res, expected)
 
 
+def test_groupby_aggregate_directory(reduction_func):
+    # GH#32793
+    if reduction_func not in ["corrwith", "nth"]:
+        obj = DataFrame([[0, 1], [0, np.nan]])
+
+        obj.convert_dtypes()
+        df_agg_last = obj.groupby(0).agg(reduction_func)
+        df_agg_last_dir = obj.groupby(0).agg({1: reduction_func})
+
+        if reduction_func in ["size", "ngroup"]:
+            tm.assert_equal(df_agg_last.values, df_agg_last_dir[1].values)
path: pandas/tests/groupby/aggregate/test_aggregate.py
text: @user1:
use tm.assert_series_equal which also compares dtypes, we don't want to use .values in tests.

diff_hunk: @@ -1327,6 +1327,23 @@ def func(ser):
     tm.assert_frame_equal(res, expected)
 
 
+def test_groupby_aggregate_directory(reduction_func):
+    # GH#32793
+    if reduction_func not in ["corrwith", "nth"]:
+        obj = DataFrame([[0, 1], [0, np.nan]])
+
+        obj.convert_dtypes()
+        df_agg_last = obj.groupby(0).agg(reduction_func)
path: pandas/tests/groupby/aggregate/test_aggregate.py
text: @user1:
can you change these names more meaningful

result_reduced_series
result_reduced_frame