Reshape wide to long in pandas
Update
As George Liu has shown in another answer, pd.melt
is the idiomatic, flexible and fast solution to this problem. Do not use unstack
for this.
unstack
returns a series with a multiindex:
In [38]: df.unstack() Out[38]: date AA 05/03 1 06/03 4 07/03 7 08/03 5 BB 05/03 2 06/03 5 07/03 8 08/03 7 CC 05/03 3 06/03 6 07/03 9 08/03 1 dtype: int64
You can call reset_index on the returning series:
In [39]: df.unstack().reset_index() Out[39]: level_0 date 00 AA 05-03 11 AA 06-03 42 AA 07-03 73 AA 08-03 54 BB 05-03 25 BB 06-03 56 BB 07-03 87 BB 08-03 78 CC 05-03 39 CC 06-03 610 CC 07-03 911 CC 08-03 1
Or construct a dataframe with a multiindex:
In [40]: pd.DataFrame(df.unstack()) Out[40]: 0 date AA 05-03 1 06-03 4 07-03 7 08-03 5BB 05-03 2 06-03 5 07-03 8 08-03 7CC 05-03 3 06-03 6 07-03 9 08-03 1
Use pandas.melt to transform from wide to long:
df = pd.DataFrame({ 'date' : ['05/03', '06/03', '07/03', '08/03'], 'AA' : [1, 4, 7, 5], 'BB' : [2, 5, 8, 7], 'CC' : [3, 6, 9, 1]}).set_index('date')df AA BB CCdate 05/03 1 2 306/03 4 5 607/03 7 8 908/03 5 7 1
To convert, we just need to reset the index and then melt:
df = df.reset_index()pd.melt(df, id_vars='date', value_vars=['AA', 'BB', 'CC'])
this is the final result:
date variable value0 05/03 AA 11 06/03 AA 42 07/03 AA 73 08/03 AA 54 05/03 BB 25 06/03 BB 56 07/03 BB 87 08/03 BB 78 05/03 CC 39 06/03 CC 610 07/03 CC 911 08/03 CC 1