Search code examples
pythonpandasdataframenumpymulti-index

Add new row as header in multiIndexed dataframe


I have a dataframe which has days, year, a1, a2, b1 columns.

enter image description here

I want to create excel like in this format enter image description here

I tried multiindexing and pivot table to create header in this format.but not able to generate o/p in this format.

table = pd.pivot_table(df,  index=['days'],
                columns=['year'], fill_value=0)
print(table)

with multiindexing

unique_kpis = df["year"].unique()
l = ['a1', 'a2', 'b1']
header = pd.MultiIndex.from_product([unique_kpis,
                                 l],
                                names=['year','days']).to_list()

Input data:

[{'days': 1, 'year': 'A', 'a1': 1001, 'a2': 1002, 'b1': 45}, {'days': 2, 'year': 'B', 'a1': 452, 'a2': 453, 'b1': 345}, {'days': 3, 'year': 'A', 'a1': 1001, 'a2': 10, 'b1': 34}, {'days': 4, 'year': 'B', 'a1': 3456, 'a2': 453, 'b1': 345}, {'days': 5, 'year': 'A', 'a1': 1003, 'a2': 123, 'b1': 34}, {'days': 6, 'year': 'B', 'a1': 3456, 'a2': 453, 'b1': 345}]

Solution

  • Use DataFrame.sort_index first and then create tuples for new level:

    print (df)
       days year  a1  a2  b1
    0     1    A   4   5   4
    1     2    A   7   5   4
    2     1    B   8   2   0
    3     2    B   9   5   1
    
    
    table = pd.pivot_table(df,  index=['days'],
                    columns=['year'], fill_value=0).sort_index(axis=1, level=1)
    
    table.columns = pd.MultiIndex.from_tuples([(b, f'Total {a[0].upper()}', a) 
                                               for a, b in table.columns])
    print (table)
               A                  B           
         Total A    Total B Total A    Total B
              a1 a2      b1      a1 a2      b1
    days                                      
    1          4  5       4       8  2       0
    2          7  5       4       9  5       1