'Pandas: transform column names to row values

I'm trying to achieve the transformation below on a pandas DataFrame. The Date columns are essentially being expanded to multiple rows and we get an entry per month instead of one column per month:

Source DataFrame:

    Food    Type       Eaten 2018-01    Eaten 2018-02   Eaten 2018-03
0   Apple   Fruit      3                4               0
1   Pizza   Fast Food  2                1               3
2   Cake    Desert     3                6               7

Target DataFrame:

        Food    Type        Month      Eaten
0       Apple   Fruit       2018-01    3
1       Apple   Fruit       2018-02    4
2       Apple   Fruit       2018-03    0
3       Pizza   Fast Food   2018-01    2
4       Pizza   Fast Food   2018-02    1
5       Pizza   Fast Food   2018-03    3
6       Cake    Desert      2018-01    3
7       Cake    Desert      2018-02    6
8       Cake    Desert      2018-03    7

The ordering of the target DataFrame is not important.



Solution 1:[1]

This is a typical wide_to_long question

pd.wide_to_long(df,'Eaten ',i=['Food','Type'],j='Month').reset_index()
Out[38]: 
    Food       Type    Month  Eaten 
0  Apple      Fruit  2018-01       3
1  Apple      Fruit  2018-02       4
2  Apple      Fruit  2018-03       0
3  Pizza  Fast Food  2018-01       2
4  Pizza  Fast Food  2018-02       1
5  Pizza  Fast Food  2018-03       3
6   Cake     Desert  2018-01       3
7   Cake     Desert  2018-02       6
8   Cake     Desert  2018-03       7

Solution 2:[2]

I believe the melt function also satisfies this. Pandas doc says wide_to_long is more user friendly but the melt function allows more flexibility. With melt:

df.melt(id_vars=['Food','Type'],var_name = 'Month', value_name = 'Eaten')

The id_vars value represents which columns you want to stay put. The remaining columns will be rotated down.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 BENY
Solution 2