Repository: pandas-dev/pandas
Pull request: TST: add test for empty frame groupby dtypes consistency
- [x] closes #20888
- [x] tests added / passed
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry


Problem statement:
Groupby on empty frame different results based on dtypes.
#### Code Sample, a copy-pastable example if possible

```python
In [117]: import pandas as pd

In [118]: df = pd.DataFrame({"a":[1], "b":[2], "c":[3], "d":[4]})

In [119]: group_keys = ["a", "b", "c"]

In [120]: g = df[df.a==2].groupby(group_keys)

In [121]: g.first().index
Out[121]:
MultiIndex(levels=[[], [], []],
           labels=[[], [], []],
           names=[u'a', u'b', u'c'])
# Change the dtype for "d"
In [122]: df = pd.DataFrame({"a":[1], "b":[2], "c":[3], "d":["d"]})

In [123]: g = df[df.a==2].groupby(group_keys)

In [124]: g.first().index
Out[124]: Index([], dtype='object')

# Version 0.18
In [36]: g.first().index
Out[36]:
MultiIndex(levels=[[], [], []],
           labels=[[], [], []],
           names=[u'a', u'b', u'c'])

```
#### Problem description

The groupby should return multi-index in both cases.  In one case when we have all int64 data, the resultant groupby on an empty frame returns the multi-index.  When we have a str (object) dtype, the return is an empty index.  Not consistent.  Previous version, 0.18.0 returned multi-index in both cases.

#### Expected Output
```python
In [36]: g.first().index
Out[36]:
MultiIndex(levels=[[], [], []],
           labels=[[], [], []],
           names=[u'a', u'b', u'c'])
```
#### Output of ``pd.show_versions()``

<details>

INSTALLED VERSIONS
------------------
commit: None
python: 2.7.14.final.0
python-bits: 64
OS: Linux
OS-release: 3.10.0-327.36.3.el7.x86_64
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: C
LANG: en_US.UTF-8
LOCALE: None.None

pandas: 0.22.0
pytest: 3.5.0
pip: 9.0.3
setuptools: 39.0.1
Cython: 0.28.2
numpy: 1.14.2
scipy: 1.0.1
pyarrow: 0.9.0
xarray: 0.10.2
IPython: 5.6.0
sphinx: 1.7.2
patsy: 0.5.0
dateutil: 2.7.2
pytz: 2018.4
blosc: None
bottleneck: 1.2.1
tables: 3.4.2
numexpr: 2.6.4
feather: None
matplotlib: 2.2.2
openpyxl: 2.5.2
xlrd: 1.1.0
xlwt: 1.3.0
xlsxwriter: 1.0.2
lxml: 4.2.1
bs4: 4.3.2
html5lib: 0.999
sqlalchemy: 1.2.6
pymysql: None
psycopg2: 2.7.4 (dt dec pq3 ext lo64)
jinja2: 2.10
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None


</details>

Hints from issue discussion:
Can confirm this was happening in 0.22 but looks to be fine on master
What would be the prescribed workaround in 0.22?
Yup looks to work on master. Could use a test.


```
In [181]: In [117]: import pandas as pd
     ...:
     ...: In [118]: df = pd.DataFrame({"a":[1], "b":[2], "c":[3], "d":[4]})
     ...:
     ...: In [119]: group_keys = ["a", "b", "c"]
     ...:
     ...: In [120]: g = df[df.a==2].groupby(group_keys)
     ...:
     ...: In [121]: g.first().index
Out[181]: MultiIndex([], names=['a', 'b', 'c'])

In [182]: In [122]: df = pd.DataFrame({"a":[1], "b":[2], "c":[3], "d":["d"]})
     ...:

In [183]: In [123]: g = df[df.a==2].groupby(group_keys)
     ...:

In [184]: In [124]: g.first().index
     ...:
Out[184]: MultiIndex([], names=['a', 'b', 'c'])

In [185]: In [36]: g.first().index
     ...:
Out[185]: MultiIndex([], names=['a', 'b', 'c'])

In [186]: pd.__version__
Out[186]: '0.26.0.dev0+682.g08ab156eb'
```

Commit message: use parameterization

Patch to review:
diff --git a/pandas/tests/test_multilevel.py b/pandas/tests/test_multilevel.py
index 79c9fe2b60bd9..33a4eca16bf75 100644
--- a/pandas/tests/test_multilevel.py
+++ b/pandas/tests/test_multilevel.py
@@ -1490,6 +1490,16 @@ def test_frame_dict_constructor_empty_series(self):
         DataFrame({"foo": s1, "bar": s2, "baz": s3})
         DataFrame.from_dict({"foo": s1, "baz": s3, "bar": s2})
 
+    @pytest.mark.parametrize("d", [4, "d"])
+    def test_empty_frame_groupby_dtypes_consistency(self, d):
+        # GH 20888
+        group_keys = [...]
+        df = DataFrame({"a": [1], "b": [2], "c": [3], "d": [d]})
+        g = df[df.a == 2].groupby(group_keys)
+        result = g.first().index
+        expected = Index([], dtype=int)
+        tm.assert_index_equal(result, expected)
+
     def test_multiindex_na_repr(self):
         # only an issue with long columns
         df3 = DataFrame(


Code review comments:
diff_hunk: @@ -1490,6 +1490,16 @@ def test_frame_dict_constructor_empty_series(self):
         DataFrame({"foo": s1, "bar": s2, "baz": s3})
         DataFrame.from_dict({"foo": s1, "baz": s3, "bar": s2})
 
+    @pytest.mark.parametrize("d", [4, "d"])
+    def test_empty_frame_groupby_dtypes_consistency(self, d):
+        # GH 20888
+        group_keys = [...]
path: pandas/tests/test_multilevel.py
text: @user1:
```suggestion
        group_keys = ["a", "b", "c"]
```

I used ellipses as shorthand to indicate you use `group_keys = ["a", "b", "c"]`

@author:
Sorry - my bad. I put back the correct `group_keys`.