This may be a cleaner solution for any number of groups:
https://stackoverflow.com/a/47849462/29951167
However, as the col4 is not numeric, it needs to be modified like this:
colGrp = ['col1','col2','col3']
df = (pd.pivot_table(df,
index=colGrp,
columns=df.groupby(colGrp).cumcount().add(1),
values=['val','col4'],
aggfunc='first')).reset_index()
df.columns=df.columns.map('{0[0]}_{0[1]}'.format)
df.columns.values[:len(colGrp)]=colGrp