Having a dataframe like this:
I would like to know what would be the most efficient way to transform it into this othe one:
I tried to generate all the combinations between Time column and days and then manually create the Value column by checking the given Day-Time cell, but Im sure it must be a more efficient way
CodePudding user response:
IF the original index is not important for you,
You could also use the .melt()
method which has the advantage of grouping the days so you have the values for 1 day after another:
df1 = df.melt(id_vars='Time', var_name='Day', value_name='Value')
Result:
index | Time | Day | Value |
---|---|---|---|
0 | 6am-2pm | Day1 | 15.4 |
1 | 2pm-10pm | Day1 | 15.0 |
2 | 10pm-6am | Day1 | 14.0 |
3 | 6am-2pm | Day2 | 13.4 |
4 | 2pm-10pm | Day2 | 2.1 |
5 | 10pm-6am | Day2 | 22.0 |
6 | 6am-2pm | Day3 | 45.0 |
7 | 2pm-10pm | Day3 | 3.4 |
8 | 10pm-6am | Day3 | 35.0 |
You could even rearrange the columns index like this to make it more readable in my own opinion:
df1 = df1.reindex(columns=['Day','Time','Value'])
Result:
index | Day | Time | Value |
---|---|---|---|
0 | Day1 | 6am-2pm | 15.4 |
1 | Day1 | 2pm-10pm | 15.0 |
2 | Day1 | 10pm-6am | 14.0 |
3 | Day2 | 6am-2pm | 13.4 |
4 | Day2 | 2pm-10pm | 2.1 |
5 | Day2 | 10pm-6am | 22.0 |
6 | Day3 | 6am-2pm | 45.0 |
7 | Day3 | 2pm-10pm | 3.4 |
8 | Day3 | 10pm-6am | 35.0 |
CodePudding user response:
Use set_index
and stack
:
out = (df.set_index('Time').stack().rename_axis(index=['Time', 'Day'])
.rename('Value').reset_index())
print(out)
# Output
Time Day Value
0 6am – 2pm Day1 15.4
1 6am – 2pm Day2 13.4
2 6am – 2pm Day3 45.0
3 2pm – 10pm Day1 15.0
4 2pm – 10pm Day2 2.1
5 2pm – 10pm Day3 3.4
6 10pm – 6am Day1 14.0
7 10pm – 6am Day2 22.0
8 10pm – 6am Day3 35.0