在pandas MultiIndex前添加一层级别
我有一个数据框(DataFrame),它的索引是多层的,这个多层索引是在进行一些分组后创建的:
import numpy as np
import pandas as pd
from numpy.random import randn
df = pd.DataFrame({'A' : ['a1', 'a1', 'a2', 'a3'],
'B' : ['b1', 'b2', 'b3', 'b4'],
'Vals' : randn(4)}
).groupby(['A', 'B']).sum()
# Vals
# A B
# a1 b1 -1.632460
# b2 0.596027
# a2 b3 -0.619130
# a3 b4 -0.002009
我想在这个多层索引的前面加一个新的层级,让它变成像下面这样的样子:
# Vals
# FirstLevel A B
# Foo a1 b1 -1.632460
# b2 0.596027
# a2 b3 -0.619130
# a3 b4 -0.002009
6 个回答
60
我觉得这是一个更通用的解决方案:
# Convert index to dataframe
old_idx = df.index.to_frame()
# Insert new level at specified location
old_idx.insert(0, 'new_level_name', new_level_values)
# Convert back to MultiIndex
df.index = pandas.MultiIndex.from_frame(old_idx)
相比其他答案,这个方法有一些优点:
- 你可以在任何位置添加新的层级,而不仅仅是最上面。
- 这个方法只是对索引进行操作,不需要像拼接那样去处理数据。
- 它不需要添加一个额外的列作为中间步骤,这样可以避免破坏多层列索引。
178
你可以先把它作为一个普通的列添加,然后再把它加到当前的索引上,像这样:
df['Firstlevel'] = 'Foo'
df.set_index('Firstlevel', append=True, inplace=True)
如果需要的话,可以用下面的代码来改变顺序:
df.reorder_levels(['Firstlevel', 'A', 'B'])
这样就会得到:
Vals
Firstlevel A B
Foo a1 b1 0.871563
b2 0.494001
a2 b3 -0.167811
a3 b4 -1.353409
编辑
还有一个更简短的解决方案(省去了重新排序的步骤):
df['Firstlevel'] = 'Foo'
df.set_index(['Firstlevel', df.index], inplace=True)
或者你也可以这样做(使用 axis=1
来处理列):
df = pd.concat([df], keys=["Firstlevel"], axis=0)
261
用 pandas.concat()
这个方法,可以很简单地在一行代码里完成这个操作:
import pandas as pd
pd.concat([df], keys=['Foo'], names=['Firstlevel'])
还有一种更简短的方法:
pd.concat({'Foo': df}, names=['Firstlevel'])
这个方法可以应用到很多数据框上,详细信息可以查看 文档。