Reputation: 861
I have a dataframe that looks like this:
df = pd.DataFrame({'Date': {0: '01/08/2016 0:00', 1: '01/08/2016 1:00', 2: '01/08/2016 2:00'},
'amount_1': {0: 29189, 1: 27614, 2: 26579},
'amount_2': {0: 26277, 1: 24992, 2: 23533},
'target': {0: 28602, 1: 27112, 2: 25975}})
I want to keep Date and target columns the same and transpose amount_1 and amount_2 rows while keeping their order. So that 3 columns after Date column belong to amount_1 for each hour then comes amount_2 columns for each hour.
This is what I tried so far.
df_t = df.melt(id_vars=['Date','target']).drop('variable', 1).sort_values(['Date','target'])
df_t.T
My desired output is:
df_t = pd.DataFrame({'Date': {0: '01/08/2016 0:00', 1: '01/08/2016 1:00', 2: '01/08/2016 2:00'},
'amount_1_hour0': {0: 29189, 1: 29189, 2: 29189},
'amount_1_hour1': {0: 27614, 1: 27614, 2: 27614},
'amount_1_hour2': {0: 26579, 1: 26579, 2: 26579},
'amount_2_hour0': {0: 26277, 1: 26277, 2: 26277},
'amount_2_hour1': {0: 24992, 1: 24992, 2: 24992},
'amount_2_hour2': {0: 23533, 1: 23533, 2: 23533},
'target': {0: 28602, 1: 27112, 2: 25975}})
Upvotes: 1
Views: 579
Reputation: 863301
I think you need:
#convert values to datetimes
df['Date'] = pd.to_datetime(df['Date'])
#create hour column
df['h'] = df['Date'].dt.hour
#melting by 3 columns
df = df.melt(id_vars=['Date','target', 'h'])
#add hours to amounts strings (variable column)
df['variable'] += '_hour' + df['h'].astype(str)
#pivoting
df = df.pivot_table(index=['Date','target'], columns='variable', values='value').reset_index()
#replace missing values per days
df = df.groupby(df['Date'].dt.date).apply(lambda x: x.ffill().bfill())
print (df)
variable Date target amount_1_hour0 amount_1_hour1 \
0 2016-01-08 00:00:00 28602 29189.0 27614.0
1 2016-01-08 01:00:00 27112 29189.0 27614.0
2 2016-01-08 02:00:00 25975 29189.0 27614.0
variable amount_1_hour2 amount_2_hour0 amount_2_hour1 amount_2_hour2
0 26579.0 26277.0 24992.0 23533.0
1 26579.0 26277.0 24992.0 23533.0
2 26579.0 26277.0 24992.0 23533.0
EDIT:
df = pd.DataFrame({'Date': {0: '01/08/2016 0:00', 1: '01/08/2016 2:00', 2: '01/08/2016 10:00'},
'amount_1': {0: 29189, 1: 27614, 2: 26579},
'amount_2': {0: 26277, 1: 24992, 2: 23533},
'target': {0: 28602, 1: 27112, 2: 25975}})
print (df)
Date amount_1 amount_2 target
0 01/08/2016 0:00 29189 26277 28602
1 01/08/2016 2:00 27614 24992 27112
2 01/08/2016 10:00 26579 23533 25975
#convert values to datetimes
df['Date'] = pd.to_datetime(df['Date'])
#create hour column
df['h'] = df['Date'].dt.hour
#melting by 3 columns
df = df.melt(id_vars=['Date','target', 'h'])
#pivoting
df = df.pivot_table(index=['Date','target'], columns=['variable','h'], values='value')
#join MultiIndex with hours
df.columns = df.columns.map(lambda x: f'{x[0]}_hour{x[1]}')
df = df.reset_index()
#replace missing values per days
df = df.groupby(df['Date'].dt.date).apply(lambda x: x.ffill().bfill())
print (df)
Date target amount_1_hour0 amount_1_hour2 \
0 2016-01-08 00:00:00 28602 29189.0 27614.0
1 2016-01-08 02:00:00 27112 29189.0 27614.0
2 2016-01-08 10:00:00 25975 29189.0 27614.0
amount_1_hour10 amount_2_hour0 amount_2_hour2 amount_2_hour10
0 26579.0 26277.0 24992.0 23533.0
1 26579.0 26277.0 24992.0 23533.0
2 26579.0 26277.0 24992.0 23533.0
Upvotes: 2