Reputation: 659
I have the following pandas df:
Window 5 15 30 45
feature col0 col1 col2 col0 col1 col2 col0 col1 col2 col0 col1 col2
metric mean std mean std mean std mean std mean std mean std mean std mean std mean std mean std mean std mean std
0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 -0.878791 1.453479 -0.265591 0.712361 0.532332 0.894304 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 -0.748535 1.459479 -0.023874 1.250110 0.913094 1.134599 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
It has 3 levels which I would like to flatten to:
col0_5_mean col0_5_std col0_15_mean col0_15_std col0_30_mean col0_30_std col0_45_mean col0_45_std col1_5_mean col1_5_std...
So order should be feature_window_metric.
The df is generated by:
import numpy as np
import pandas as pd
np.random.seed(123)
# def add_mean_std_cols3(df):
df = pd.DataFrame(np.random.randn(100,3)).add_prefix('col')
windows = [5, 15, 30, 45]
stats = ['mean', 'std']
cols = pd.MultiIndex.from_product([windows, df.columns, stats],
names=['window', 'feature', 'metric'])
df2 = pd.DataFrame(np.empty((df.shape[0], len(cols))), columns=cols,
index=df.index)
for window in windows:
df2.loc[:, window] = df.rolling(window=window).agg(stats).values
print df2
So far I tried the following solution among others:
From Pandas dataframe with multiindex column - merge levels
df2.columns = df2.columns.map('|'.join)
TypeError: sequence item 0: expected string, long found
I appreciate suggestions,
Thanks
Upvotes: 1
Views: 1008
Reputation: 153460
You can still use map
with format
:
df2.columns = df2.columns.map('{0[0]} | {0[1]} | {0[2]}'.format)
Upvotes: 2
Reputation: 76917
Use
In [1914]: df2.columns = ['{1}_{0}_{2}'.format(*c) for c in df2.columns]
In [1915]: df2.columns
Out[1915]:
Index([u'col0_5_mean', u'col0_5_std', u'col1_5_mean', u'col1_5_std',
u'col2_5_mean', u'col2_5_std', u'col0_15_mean', u'col0_15_std',
u'col1_15_mean', u'col1_15_std', u'col2_15_mean', u'col2_15_std',
u'col0_30_mean', u'col0_30_std', u'col1_30_mean', u'col1_30_std',
u'col2_30_mean', u'col2_30_std', u'col0_45_mean', u'col0_45_std',
u'col1_45_mean', u'col1_45_std', u'col2_45_mean', u'col2_45_std'],
dtype='object')
In [1916]: df2.head(2)
Out[1916]:
col0_5_mean col0_5_std col1_5_mean col1_5_std col2_5_mean col2_5_std \
0 NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN
col0_15_mean col0_15_std col1_15_mean col1_15_std ... \
0 NaN NaN NaN NaN ...
1 NaN NaN NaN NaN ...
col1_30_mean col1_30_std col2_30_mean col2_30_std col0_45_mean \
0 NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN
col0_45_std col1_45_mean col1_45_std col2_45_mean col2_45_std
0 NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN
[2 rows x 24 columns]
Upvotes: 2