Repository: pandas-dev/pandas

Issue:
GroupBy(axis=1) Does Not Offer Implicit Selection By Columns Name(s)
#### Code Sample, a copy-pastable example if possible

```python
import pandas as pd
import numpy as np

df = pd.DataFrame(np.arange(12).reshape(3, 4), index=[0, 1, 0], columns=[10, 20, 10, 20])
df.index.name = "y"
df.columns.name = "x"

print df

print
print "Grouped along index:"
print df.groupby(by="y").sum()

print
print "Grouped along columns:"
# The following raises a KeyError even though  "x" is a column name
# (like "y" above, which is an index name):
df.groupby(by="x", axis=1).sum()
```
#### Problem description

The exception at the end is surprising: the intent is clearly to group by columns, on the "x" column label.

Furthermore, the documentation for `groupby()` seems to confirm this, as it states for the "by" argument that "A str or list of strs may be passed to group by the columns in ``self``".

#### Expected Output

A dataframe with index [0, 1, 0] but grouped (and summed) columns [10, 20].

I wasn't able to test with the latest Pandas version, sorry!

#### Output of ``pd.show_versions()``

<details>

INSTALLED VERSIONS
------------------
commit: None
python: 2.7.13.final.0
python-bits: 64
OS: Linux
OS-release: 2.6.32-642.15.1.el6.x86_64
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: None.None

pandas: 0.21.1
pytest: 3.2.3
pip: 9.0.1
setuptools: 28.8.0
Cython: 0.27.3
numpy: 1.13.3
scipy: 0.19.1
pyarrow: None
xarray: 0.8.2
IPython: 5.1.0
sphinx: 1.4.4
patsy: 0.4.1
dateutil: 2.6.1
pytz: 2017.2
blosc: None
bottleneck: None
tables: 3.4.4
numexpr: 2.6.5
feather: None
matplotlib: 2.1.2
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: 4.6.0
html5lib: 0.9999999
sqlalchemy: 1.2.18
pymysql: None
psycopg2: None
jinja2: 2.8
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None
</details>


Discussion:

Resolving patch:
diff --git a/pandas/core/groupby/grouper.py b/pandas/core/groupby/grouper.py
--- a/pandas/core/groupby/grouper.py
+++ b/pandas/core/groupby/grouper.py
@@ -606,10 +606,10 @@ def is_in_obj(gpr):
         elif is_in_axis(gpr):  # df.groupby('name')
             if gpr in obj:
                 if validate:
-                    obj._check_label_or_level_ambiguity(gpr)
+                    obj._check_label_or_level_ambiguity(gpr, axis=axis)
                 in_axis, name, gpr = True, gpr, obj[gpr]
                 exclusions.append(name)
-            elif obj._is_level_reference(gpr):
+            elif obj._is_level_reference(gpr, axis=axis):
                 in_axis, name, level, gpr = False, None, gpr, None
             else:
                 raise KeyError(gpr)


Test patch:
diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py
--- a/pandas/tests/groupby/test_groupby.py
+++ b/pandas/tests/groupby/test_groupby.py
@@ -1860,3 +1860,25 @@ def test_groupby_groups_in_BaseGrouper():
     result = df.groupby(["beta", pd.Grouper(level="alpha")])
     expected = df.groupby(["beta", "alpha"])
     assert result.groups == expected.groups
+
+
+@pytest.mark.parametrize("group_name", ["x", ["x"]])
+def test_groupby_axis_1(group_name):
+    # GH 27614
+    df = pd.DataFrame(
+        np.arange(12).reshape(3, 4), index=[0, 1, 0], columns=[10, 20, 10, 20]
+    )
+    df.index.name = "y"
+    df.columns.name = "x"
+
+    results = df.groupby(group_name, axis=1).sum()
+    expected = df.T.groupby(group_name).sum().T
+    assert_frame_equal(results, expected)
+
+    # test on MI column
+    iterables = [["bar", "baz", "foo"], ["one", "two"]]
+    mi = pd.MultiIndex.from_product(iterables=iterables, names=["x", "x1"])
+    df = pd.DataFrame(np.arange(18).reshape(3, 6), index=[0, 1, 0], columns=mi)
+    results = df.groupby(group_name, axis=1).sum()
+    expected = df.T.groupby(group_name).sum().T
+    assert_frame_equal(results, expected)