Rename Multiindex Columns in Pandas

Rename MultiIndex columns in Pandas

Use set_levels:

In [22]:
df.columns.set_levels(['b1','c1','f1'],level=1,inplace=True)
df

Out[22]:
a d
b1 c1 f1
0 1 2 3
1 10 20 30
2 100 200 300

rename sets the name for the index, it doesn't rename the column names:

In [26]:
df.columns = df.columns.rename("b1", level=1)
df

Out[26]:
a d
b1 b c f
0 1 2 3
1 10 20 30
2 100 200 300

This is why you get the error

How to rename MultiIndex columns?

You could flatten the index first, using to_flat_index:

df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]],
columns=pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1)]))

lookup = {('a', 1): 'd', ('a', 2): 'e', ('b', 1): 'f'}

# flatten index
df.columns = df.columns.to_flat_index()

# rename using lookup
result = df.rename(columns=lookup)

print(result)

Output

   d  e  f
0 1 2 3
1 4 5 6
2 7 8 9

Rename multiindex level based on other level

Update

measure_to_unit = {"Length": "m", "Weight": "kg"}

l1, l2, l3 = zip(*df.columns)
newcol = pd.MultiIndex.from_arrays([l1, l2, [measure_to_unit[i] for i in l1]])
df.set_axis(newcol, axis=1)

Output:

     Length      Weight     
Max Min Max Min
m m kg kg
0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0

If the order of your dataframe columns match the order of your index, then you can do this:

df.set_axis(pd.MultiIndex.from_arrays([measure_to_unit.keys(), measure_to_unit.values()]), axis=1)

Output:

  Length Weight
m kg
0 0.0 0.0
1 0.0 0.0

How to remove row and rename multiindex table

Let's try DataFrame.droplevel to remove level 2 from the columns, and DataFrame.rename_axis to update column axis names:

df = df.droplevel(level=2, axis=1).rename_axis(['ALIAS', 'metric'], axis=1)

Or with the index equivalent methods Index.droplevel and Index.rename:

df.columns = df.columns.droplevel(2).rename(['ALIAS', 'metric'])

df:

ALIAS  data   
metric F K
A 2 3
B 4 5
C 6 7
D 8 9

Setup:

import numpy as np
import pandas as pd

df = pd.DataFrame(
np.arange(2, 10).reshape(-1, 2),
index=list('ABCD'),
columns=pd.MultiIndex.from_arrays([
['data', 'data'],
['F', 'K'],
['C', 'B']
], names=['metric', None, None])
)

df:

metric data   
F K
C B
A 2 3
B 4 5
C 6 7
D 8 9

python pandas: rename single column label in multi-index dataframe

That is indeed something missing in rename (ideally it should let you specify the level).

Another way is by setting the levels of the columns index, but then you need to know all values for that level:

In [41]: df.columns.levels[0]
Out[41]: Index([u'1', u'2'], dtype='object')

In [43]: df.columns = df.columns.set_levels(['one', 'two'], level=0)

In [44]: df
Out[44]:
one two
A B A B
0 0.899686 0.466577 0.867268 0.064329
1 0.162480 0.455039 0.736870 0.759595
2 0.620960 0.922119 0.060141 0.669997
3 0.871107 0.043799 0.080080 0.577421

In [45]: df.columns.levels[0]
Out[45]: Index([u'one', u'two'], dtype='object')

pandas won't rename multiindex column name

df.columns.set_levels(['Boom1','Boom2','Boom3'],level=0,inplace=True)

If your columns are Boom1, ..., Boom1000, first create a list of names by

ll = [f"Boom{i}" for i in range(1,1001)]
df.columns.set_levels(ll,level=0,inplace=True)

Rename multi index dataframe pandas

Use Index.map with join if all values are strings:

df.columns = df.columns.map('_'.join)

Or format or f-strings - working with numeric values in levels too:

df.columns = df.columns.map('{0[0]}_{0[1]}'.format)
df.columns = df.columns.map(lambda x: f'{x[0]}_{x[1]}')

Last DataFrame.reset_index for convert MultiIndex in Index to columns:

df = df.reset_index()
print (df)
name age empId Issue_high Issue_med Issue_low
0 Jack 44 Ab1 0 1 0
1 Bob 34 Ab2 0 0 1
2 Mike 52 Ab6 1 1 0


Related Topics



Leave a reply



Submit