Pandas - Concat different column levels MultiIndex DataFrames

Viewed 423

Imagine we have a DataFrame created like this:

tmp_df = pd.DataFrame(index=xrange(10), columns=['3-1','3-2'])
tmp_df = pd.concat({'2-1': tmp_df, '2-2': tmp_df},axis=1)
tmp_df = pd.concat({'1-1': tmp_df, '1-2': tmp_df}, axis=1)

Which gives:

   1-1                 1-2               
   2-1       2-2       2-1       2-2     
   3-1  3-2  3-1  3-2  3-1  3-2  3-1  3-2
0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
1  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
2  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
3  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
5  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
6  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
7  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
8  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
9  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN

Thus, we have a three-level column indexed DataFrame. Nonetheless, if we want to concatenate to this a different two-level column indexed DataFrame such as:

tmp2_df = pd.Series(np.nan,index=xrange(10))
tmp2_df = pd.concat({'1-3':pd.concat({'2-1': tmp2_df, '2-2': tmp2_df},axis=1)},axis=1)

  1-3    
  2-1 2-2
0 NaN NaN
1 NaN NaN
2 NaN NaN
3 NaN NaN
4 NaN NaN
5 NaN NaN
6 NaN NaN
7 NaN NaN
8 NaN NaN
9 NaN NaN

Using pd.concat(...) destroys the hierarchy:

pd.concat([tmp_df,tmp2_df],axis=1).columns

Index([(u'1-1', u'2-1', u'3-1'), (u'1-1', u'2-1', u'3-2'),
       (u'1-1', u'2-2', u'3-1'), (u'1-1', u'2-2', u'3-2'),
       (u'1-2', u'2-1', u'3-1'), (u'1-2', u'2-1', u'3-2'),
       (u'1-2', u'2-2', u'3-1'), (u'1-2', u'2-2', u'3-2'),
               (u'1-3', u'2-1'),         (u'1-3', u'2-2')],
      dtype='object')

How can we mantain the column index hierarchy in a way that for tmp2_df there is not a 3rd level of column index? Output should be something like:

   1-1                 1-2                 1-3
   2-1       2-2       2-1       2-2       2-1  2-2
   3-1  3-2  3-1  3-2  3-1  3-2  3-1  3-2  
0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
1  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
2  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
3  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
5  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
6  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
7  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
8  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
9  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN

I am aware that you can do things like:

tmp_df['test'] = pd.Series(np.nan,index=xrange(10))

   1-1                 1-2                test
   2-1       2-2       2-1       2-2          
   3-1  3-2  3-1  3-2  3-1  3-2  3-1  3-2     
0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
1  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
2  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
3  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
5  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
6  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
7  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
8  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
9  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN

But this solution does not work for appending DataFrames:

ValueError: Wrong number of items passed 2, placement implies 1
0 Answers
Related