Reputation: 772
I'm trying to reorder/swaplevel/pivot/something columns in a pandas dataframe. The columns are a MultiIndex, but I can't find the sauce to do what I want.
The fastest varying column in my multiIndex is month, but I would like it to be the slowest varying column.
I've got a nbviewer notebook if you would like to try it out yourself: http://nbviewer.ipython.org/gist/flamingbear/4cfac24c80fe34a67474
What I have:
+-------------------------------------------------------------------+
|+-----+------+------+-----+------+-----+-----+------+-----+-----+ |
|| |weight |extent |rank ||
|+-----+------+------+-----+------+-----+-----+------+-----+-----+ |
||month|'1Jan'|'Feb' |'Mar'|'1Jan'|'Feb'|'Mar'|'1Jan'|'Feb'|'Mar'| |
|+-----+------+------+-----+------+-----+-----+------+-----+-----+ |
||year | | | | | | | | | | |
|+-----+------+------+-----+------+-----+-----+------+-----+-----+ |
||2000 |45.1 |46.1 |25.1 |13.442|14.94|15.02|13 |17 |14 | |
|+-----+------+------+-----+------+-----+-----+------+-----+-----+ |
||2001 |85.0 |16.0 |49.0 |13.380|14.81|15.14|12 |15 |17 | |
|+-----+------+------+-----+------+-----+-----+------+-----+-----+ |
||2002 |90.0 |33.0 |82.0 |13.590|15.13|14.88|15 |22 |10 | |
|+-----+------+------+-----+------+-----+-----+------+-----+-----+ |
||2003 |47.0 |34.0 |78.0 |13.640|14.83|15.27|17 |16 |22 | |
|+-----+------+------+-----+------+-----+-----+------+-----+-----+ |
+-------------------------------------------------------------------+
What I want
+------------------------------------------------------------------+
|+-----+------+------+----+------+------+-----+------+------+----+ |
||month|1Jan |Feb |Mar ||
|+-----+------+------+----+------+------+-----+------+------+----+ |
|| |weight|extent|rank|weight|extent|rank |weight|extent|rank| |
|+-----+------+------+----+------+------+-----+------+------+----+ |
||year | | | | | | | | | | |
|+-----+------+------+----+------+------+-----+------+------+----+ |
||2000 |45.1 |13.442|13 |46.1 |14.94 |17 | 25.1 |15.02 |14 | |
|+-----+------+------+----+------+------+-----+------+------+----+ |
||2001 |85.0 |13.380|12 |16.0 |14.81 |15 | 49.0 |15.14 |17 | |
|+-----+------+------+----+------+------+-----+------+------+----+ |
||2002 |90.0 |13.590|15 |33.0 |15.13 |22 | 82.0 |14.88 |10 | |
|+-----+------+------+----+------+------+-----+------+------+----+ |
||2003 |47.0 |13.640|17 |34.0 |14.83 |16 | 78.0 |15.27 |22 | |
|+-----+------+------+-----------+------+-----+------+------+----+ |
+------------------------------------------------------------------+
Any help would be appreciated. I can work with my original DataFrame, but writing to a CSV with the desired ordering would be fantastic.
Thanks in advance, Matt
Upvotes: 54
Views: 37932
Reputation: 34014
Another method that does not need explicit index sorting is
df.stack(0).unstack()
Upvotes: 2
Reputation: 109686
Your columns are a MultiIndex. You need to reassign the DataFrame's columns with a new MultiIndex created from swapping levels of the existing one:
df.columns = df.columns.swaplevel(0, 1)
df.sort_index(axis=1, level=0, inplace=True)
>>> df
month '1Jan' 'Feb' 'Mar'
weight extent rank weight extent rank weight extent rank
year
2000 45.1 13.442 13 46.1 14.94 17 25.1 15.02 14
2001 85.0 13.380 12 16.0 14.81 15 49.0 15.14 17
2002 90.0 13.590 15 33.0 15.13 22 82.0 14.88 10
2003 47.0 13.640 17 34.0 14.83 16 78.0 15.27 22
You can then export to csv:
df.to_csv(filename)
Upvotes: 80
Reputation: 313
Since levels indices are no more mandatory you can have even more simple way to achieve the level swapping of multi-index dataframe:
df = df.swaplevel(axis='columns')
Upvotes: 9