python - 如何从多索引列数据框创建多级索引
问题描述
主要目标是从现有的df
.
假设我们有如下多级列
level1
level2
sub_name A B C
ONE TT 11 12 13
TWO TT 21 22 23
THREE TT 31 32 33
然后,预期的输出 (1)
level1
level2
A B C
TT ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
我觉得这可以通过group
OR 直接使用来实现set_index
,如下所示
df = df.groupby((slice ( None ), slice ( None ),'sub_name'),as_index = False)
或者
df=df.set_index([(slice ( None ), slice ( None ),'sub_name')])
但是,这是行不通的。
这样第一种方法返回错误
TypeError:不可散列的类型:'slice'
第二种方法
TypeError:参数“keys”可能是列键、一维数组或仅包含有效列键和一维数组的列表。接收到的列类型为 <class 'tuple'>
我可以知道实现预期目标的正确方法是什么。
重现上述错误的完整代码
import pandas as pd
df = pd.DataFrame ( {'A': [11, 21, 31],
'B': [12, 22, 32],
'C': [13, 23, 33]},
index=['ONE', 'TWO', 'THREE'] )
df.columns = pd.MultiIndex.from_product ( [['level1'], ['level2'], df.columns] )
df2 = pd.DataFrame ( ['TT'] * len ( df ), index=df.index,
columns=pd.MultiIndex.from_product ( [df.columns.levels [0],
df.columns.levels [1],
['sub_name']] ) )
# Im just curios whether there is simpler way of creating constant column like this
df = pd.concat ( [df2,df ], axis=1 )
# df = df.groupby((slice ( None ), slice ( None ),'sub_name'),as_index = False)
# df=df.set_index([(slice ( None ), slice ( None ),'sub_name')])
在贡献者的支持下。
额外的问题是是否可以TT
在不需要创建常量列的情况下添加另一个级别(即df2
)
level1
level2
A B C
main_level TT ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
解决方案
你可以试试set_index()
++++ xs()
:swaplevel()
drop()
df=(df.set_index(df.xs('sub_name',axis=1,level=2).values.squeeze(),append=True)
.swaplevel(0).drop('sub_name',axis=1,level=2))
输出:
level1
level2
A B C
TT ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
注意:您也可以使用df.loc[:,(slice(None),slice(None),'sub_name')]
代替df.xs('sub_name',axis=1,level=2)
更新:
你可以试试pd.MultiIndex.from_product()
:
df.index=pd.MultiIndex.from_product([['main_level'],['TT'],df.index.unique()])
输出:
level1
level2
A B C
main_level TT ONE 11 12 13
TWO 21 22 23
THREE 31 32 33