pythonpandas

How to make values into rows instead of columns when using pivot table in pandas


Say I have this data frame:

import pandas as pd

x = pd.DataFrame([[1, 'step', 'id', 22, 33], 
                  [2, 'step', 'id', 55, 66]], 
                  columns=['time', 'head_1', 'head_2', 'value_1', 'value_2'])

print(x)

   time head_1 head_2  value_1  value_2
0     1   step     id       22       33
1     2   step     id       55       66

Then I use pivot table like below

print(x.pivot_table(values=['value_1', 'value_2'], columns='time', index=['head_1', 'head_2']))

              value_1     value_2    
time                1   2       1   2
head_1 head_2                        
step   id          22  55      33  66

However, I really want to have value_1 and value_2 in rows instead of columns like below (a new header as head_3). That is, put value_1 and value_2 in rows and only time as column. How do I do that?

time                       1   2
head_1 head_2 head_3                       
step   id     value_1     22  55
step   id     value_2     33  66

Solution

  • One straightforward way is to melt your dataframe so value_1 and value_2 become labels in single column and then pivot on that. Like:

    import pandas as pd
    
    x = pd.DataFrame(
        [
            [1, 'step', 'id', 22, 33],
            [2, 'step', 'id', 55, 66]
        ],
        columns=['time','head_1', 'head_2', 'value_1', 'value_2']
    )
    
    melted = x.melt(
        id_vars=['time','head_1', 'head_2'],
        value_vars=['value_1','value_2'],
        var_name='head_3',
        value_name='val'
    )
    
    result = melted.pivot_table(
        index=['head_1','head_2','head_3'],
        columns='time',
        values='val',
        aggfunc='first'
    )
    

    You’ll get:

    time                 1   2
    head_1 head_2 head_3        
    step   id     value_1  22  55
                   value_2 33  66
    

    This places value_1 and `value_2 in rows as you wanted with only time going across columns