4

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.

smci
  • 32,567
  • 20
  • 113
  • 146
velxundussa
  • 91
  • 1
  • 10

2 Answers2

7

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
BENY
  • 317,841
  • 20
  • 164
  • 234
3

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.

Whip
  • 133
  • 2
  • 10