Repository: pandas-dev/pandas

Issue:
Panel arguments can no longer be named.
This code used to work some time around version 0.10, but now generates a ValueError:

In [14]: y
Out[14]: 
<class 'pandas.core.panel.Panel'>
Dimensions: 2 (items) x 3 (major_axis) x 2 (minor_axis)
Items axis: z1 to z2
Major_axis axis: 0 to 2
Minor_axis axis: a to b

In [15]: y.transpose('minor', 'major', 'items')
Out[15]: 
<class 'pandas.core.panel.Panel'>
Dimensions: 2 (items) x 3 (major_axis) x 2 (minor_axis)
Items axis: a to b
Major_axis axis: 0 to 2
Minor_axis axis: z1 to z2
## In [16]: y.transpose( items='minor', major='major', minor='items')

ValueError                                Traceback (most recent call last)
<ipython-input-16-00ebdc16128e> in <module>()
----> 1 y.transpose( items='minor', major='major', minor='items')

/usr/local/lib/python2.7/dist-packages/pandas-0.12.0.dev_be25266-py2.7-linux-x86_64.egg/pandas/core/panel.pyc in transpose(self, _args, *_kwargs)
   1176                 except (IndexError):
   1177                     raise ValueError(
-> 1178                         "not enough arguments specified to transpose!")
   1179 
   1180         axes = [self._get_axis_number(kwargs[a]) for a in self._AXIS_ORDERS]

ValueError: not enough arguments specified to transpose!



Discussion:
try 

```
y.transpose(items='minor',major_axis='major',minor_axis='items')
```

`minor` and `major` are axis aliases but don't allow them here...let me take a look

@jreback passing only kwargs will fail here because `args` will be an empty list thus raising an `IndexError`. use of args and kwargs here seems like a bad idea since you already know precisely how many and the names of the axes. why not just have named arguments here? if they must be kept you can just assert args or kwargs and len(args) + len(kwargs) == 3 and then the code should work.

his is an easy fix
it just needs to accept the aliases 
I'll fix tom (I had meant to keep the API the same)

@jreback I have a pr ready for this, should i submit?

oh if u have I ahead
I'll take a look


Resolving patch:
diff --git a/pandas/core/panel.py b/pandas/core/panel.py
--- a/pandas/core/panel.py
+++ b/pandas/core/panel.py
@@ -1166,16 +1166,35 @@ def transpose(self, *args, **kwargs):
         -------
         y : Panel (new object)
         """
-
         # construct the args
         args = list(args)
+        aliases = tuple(kwargs.iterkeys())
+
         for a in self._AXIS_ORDERS:
             if not a in kwargs:
-                try:
-                    kwargs[a] = args.pop(0)
-                except (IndexError):
-                    raise ValueError(
-                        "not enough arguments specified to transpose!")
+                where = map(a.startswith, aliases)
+
+                if any(where):
+                    if sum(where) != 1:
+                        raise AssertionError(
+                            'Ambiguous parameter aliases "{0}" passed, valid '
+                            'parameter aliases are '
+                            '{1}'.format([n for n, m in zip(aliases, where)
+                                          if m], self._AXIS_ALIASES))
+
+                    k = aliases[where.index(True)]
+
+                    try:
+                        kwargs[self._AXIS_ALIASES[k]] = kwargs.pop(k)
+                    except KeyError:
+                        raise KeyError('Invalid parameter alias '
+                                       '"{0}"'.format(k))
+                else:
+                    try:
+                        kwargs[a] = args.pop(0)
+                    except IndexError:
+                        raise ValueError(
+                            "not enough arguments specified to transpose!")
 
         axes = [self._get_axis_number(kwargs[a]) for a in self._AXIS_ORDERS]
 


Test patch:
diff --git a/pandas/tests/test_panel.py b/pandas/tests/test_panel.py
--- a/pandas/tests/test_panel.py
+++ b/pandas/tests/test_panel.py
@@ -1140,6 +1140,30 @@ def test_transpose(self):
         expected = self.panel.swapaxes('items', 'minor')
         assert_panel_equal(result, expected)
 
+        # test kwargs
+        result = self.panel.transpose(items='minor', major='major',
+                                      minor='items')
+        expected = self.panel.swapaxes('items', 'minor')
+        assert_panel_equal(result, expected)
+
+        # text mixture of args
+        result = self.panel.transpose('minor', major='major', minor='items')
+        expected = self.panel.swapaxes('items', 'minor')
+        assert_panel_equal(result, expected)
+
+        result = self.panel.transpose('minor', 'major', minor='items')
+        expected = self.panel.swapaxes('items', 'minor')
+        assert_panel_equal(result, expected)
+
+        ## test bad aliases
+        # test ambiguous aliases
+        self.assertRaises(AssertionError, self.panel.transpose, 'minor',
+                          maj='major', majo='items')
+
+        # test invalid kwargs
+        self.assertRaises(KeyError, self.panel.transpose, 'minor',
+                          maj='major', minor='items')
+
         result = self.panel.transpose(2, 1, 0)
         assert_panel_equal(result, expected)