ctrl-alt-delete
ctrl-alt-delete

Reputation: 3862

How can I rearrange the index level with Pandas?

The purpose of this post is to try to understand how best to manipulate dataframes with multilevels.

Create the dataframe

import numpy as np
dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('WXYZ'))
df['Portfolio']= list('ABCDEF')

df

Dataframe

            Y           Z   Portfolio
01/01/2013  1           2   A
02/01/2013  3           4   B
03/01/2013  5           6   C
04/01/2013  7           8   D
05/01/2013  9           10  E
06/01/2013  11          12  F

Pivot the dataframe

dfs_pivot = df.pivot(columns='Portfolio')

dfs_pivot

Pivoted Dateframe

              Y                         Z  
Portfolio     A   B   C   D   E   F     A   B   C   D   E    F 
2013-01-01    1   NaN NaN NaN NaN NaN   2   NaN NaN NaN NaN NaN 
2013-01-02    NaN 3   NaN NaN NaN NaN   NaN 4   NaN NaN NaN NaN 
2013-01-03    NaN NaN 5   NaN NaN NaN   NaN NaN 6   NaN NaN NaN 
2013-01-04    NaN NaN NaN 7   NaN NaN   NaN NaN NaN 8   NaN NaN 
2013-01-05    NaN NaN NaN NaN 9   NaN   NaN NaN NaN NaN 10  NaN 
2013-01-06    NaN NaN NaN NaN NaN 11    NaN NaN NaN NaN NaN 12 

How can the levels be switched to give?

Portfolio       A       B       C       D       E        F 
              Y   Z   Y   Z   Y   Z   Y   Z   Y   Z    Y   Z    
2013-01-01    1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN  
2013-01-02    NaN NaN 3   4   NaN NaN NaN NaN NaN NaN NaN NaN  
2013-01-03    NaN NaN NaN NaN 5   6   NaN NaN NaN NaN NaN NaN  
2013-01-04    NaN NaN NaN NaN NaN NaN 7   8   NaN NaN NaN NaN
2013-01-05    NaN NaN NaN NaN NaN NaN NaN NaN 9   10  NaN NaN
2013-01-06    NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 11  12

Upvotes: 1

Views: 126

Answers (1)

unutbu
unutbu

Reputation: 880547

To swap the order of the MultiIndex levels, use DataFrame.swaplevel:

import numpy as np
import pandas as pd
dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.random.randint(10, size=(6,2)), index=dates, columns=list('YZ'))
df['Portfolio']= list('ABCDEF')
dfs_pivot = df.pivot(columns='Portfolio').swaplevel(0, 1, axis=1)

yields

Portfolio     A    B    C    D    E    F    A    B    C    D    E    F
              Y    Y    Y    Y    Y    Y    Z    Z    Z    Z    Z    Z
2013-01-01  7.0  NaN  NaN  NaN  NaN  NaN  9.0  NaN  NaN  NaN  NaN  NaN
2013-01-02  NaN  4.0  NaN  NaN  NaN  NaN  NaN  3.0  NaN  NaN  NaN  NaN
2013-01-03  NaN  NaN  8.0  NaN  NaN  NaN  NaN  NaN  2.0  NaN  NaN  NaN
2013-01-04  NaN  NaN  NaN  5.0  NaN  NaN  NaN  NaN  NaN  7.0  NaN  NaN
2013-01-05  NaN  NaN  NaN  NaN  4.0  NaN  NaN  NaN  NaN  NaN  7.0  NaN
2013-01-06  NaN  NaN  NaN  NaN  NaN  3.0  NaN  NaN  NaN  NaN  NaN  9.0

To sort the columns call DataFrame.sortlevel:

dfs_pivot = dfs_pivot.sortlevel(axis=1)

yields

Portfolio     A         B         C         D         E         F     
              Y    Z    Y    Z    Y    Z    Y    Z    Y    Z    Y    Z
2013-01-01  7.0  9.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
2013-01-02  NaN  NaN  4.0  3.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
2013-01-03  NaN  NaN  NaN  NaN  8.0  2.0  NaN  NaN  NaN  NaN  NaN  NaN
2013-01-04  NaN  NaN  NaN  NaN  NaN  NaN  5.0  7.0  NaN  NaN  NaN  NaN
2013-01-05  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  4.0  7.0  NaN  NaN
2013-01-06  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  3.0  9.0

To rearrange the columns in a custom order, you could call reindex:

custom_order = [('E', 'Z'), ('D', 'Z'), ('C', 'Z'), ('F', 'Z'), ('F', 'Y'), ('B', 'Z'),
                ('C', 'Y'), ('E', 'Y'), ('A', 'Z'), ('A', 'Y'), ('B', 'Y'), ('D', 'Y')]
dfs_pivot = dfs_pivot.reindex(columns=custom_order) 

or, more simply, use column-indexing syntax:

dfs_pivot = dfs_pivot[custom_order]

which yields

Portfolio     E    D    C    F         B    C    E    A         B    D
              Z    Z    Z    Z    Y    Z    Y    Y    Z    Y    Y    Y
2013-01-01  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  9.0  7.0  NaN  NaN
2013-01-02  NaN  NaN  NaN  NaN  NaN  3.0  NaN  NaN  NaN  NaN  4.0  NaN
2013-01-03  NaN  NaN  2.0  NaN  NaN  NaN  8.0  NaN  NaN  NaN  NaN  NaN
2013-01-04  NaN  7.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  5.0
2013-01-05  7.0  NaN  NaN  NaN  NaN  NaN  NaN  4.0  NaN  NaN  NaN  NaN
2013-01-06  NaN  NaN  NaN  9.0  3.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN

Upvotes: 4

Related Questions