多级索引:在一个轴上有多个(两个以上)的索引,能够以低维度形式来表示高维度的数据。单级索引是Index对象,多级索引是MultiIndex对象。
一、创建多级索引
- 方法一:隐式创建,即给DataFrame的
index
或columns
参数传递两个或更多的数组。df1 = pd.DataFrame(np.random.randint(80, 120, size=(2, 4)), index= ['girl', 'boy'], columns=[['English', 'English', 'Chinese', 'Chinese'], ['like', 'dislike', 'like', 'dislike']]) print(df1) # 创建多级 列 索引 ------------------------------------------------------------------------------------- English Chinese like dislike like dislike girl 85 109 117 110 boy 85 111 100 107
- 方法二、显示创建,推荐使用较简单的
pd.MultiIndex.from_product
方法df2 = pd.DataFrame(np.random.randint(80, 120, size=(4, 2)), columns= ['girl', 'boy'], index=pd.MultiIndex.from_product([['English','Chinese'], ['like','dislike']])) print(df2) # 创建多级 行 索引 ------------------------------------------------------------------------------------- girl boy English like 92 98 dislike 118 99 Chinese like 109 108 dislike 108 91
二、检索多级索引
- 类似单级索引检索(loc、iloc),以
df1
数据为例df1.English ------------------------------------------------------------------------------------- like dislike girl 105 112 boy 118 87 df1.English.dislike ------------------------------------------------------------------------------------- girl 112 boy 87 Name: dislike, dtype: int64 df1.iloc[:,0:3] ------------------------------------------------------------------------------------- English Chinese like dislike like girl 85 113 82 boy 97 83 94 df1.loc['girl', ['English', 'Chinese']] ------------------------------------------------------------------------------------- English like 105 dislike 112 Chinese like 87 dislike 92 Name: girl, dtype: int64
- 多级索引的检索,可以使用更高级的方法,如xs、IndexSlice等,用到较少暂不介绍。
三、更改索引的层级
- 创建多级索引
df = pd.DataFrame(np.random.randint(80, 120, size=(6, 4)), index= pd.MultiIndex.from_product([[1, 2, 3],['girl', 'boy']]), columns=pd.MultiIndex.from_product([['English','Chinese'], ['Y','N']])) print(df) ------------------------------------------------------------------------------------- English Chinese Y N Y N 1 girl 86 99 111 105 boy 85 110 113 112 2 girl 98 106 108 94 boy 117 80 97 83 3 girl 95 81 114 95 boy 106 95 119 81
- 为多级索引命名
df.columns.names = ['Language', 'Pass'] # 设置列索引名 df.index.names = ['Class', 'Six'] # 设置行索引名 print(df) ------------------------------------------------------------------------------------- Language English Chinese Pass Y N Y N Class Six 1 girl 86 99 111 105 boy 85 110 113 112 2 girl 98 106 108 94 boy 117 80 97 83 3 girl 95 81 114 95 boy 106 95 119 81
- 更改索引的层级(swaplevel)
df.swaplevel('Six','Class') # 更改行索引的层级 ------------------------------------------------------------------------------------- Language English Chinese Pass Y N Y N Six Class girl 1 86 99 111 105 boy 1 85 110 113 112 girl 2 98 106 108 94 boy 2 117 80 97 83 girl 3 95 81 114 95 boy 3 106 95 119 81
四、多级索引的值排序(sort_index)
- 方法一
df.sort_index(level=0, axis=0, ascending=False) # 对行索引Class的值进行降序排列 ------------------------------------------------------------------------------------- Language English Chinese Pass Y N Y N Class Six 3 girl 95 81 114 95 boy 106 95 119 81 2 girl 98 106 108 94 boy 117 80 97 83 1 girl 86 99 111 105 boy 85 110 113 112
- 方法二:使用sortlevel方法,从0.20.0版本开始,已经被弃用
五、多级索引汇总统计
- 示例一
df.sum(level=1) 或df.sum(level='Six') # 对行索引Six进行求和 ------------------------------------------------------------------------------------- Language English Chinese Pass Y N Y N Six girl 279 286 333 294 boy 308 285 329 276
- 示例二
df.sum(level=0, axis=1) 或 df.sum(level='Language', axis=1) # 对列索引Language进行求和 ------------------------------------------------------------------------------------- Language English Chinese Class Six 1 girl 185 216 boy 195 225 2 girl 204 202 boy 197 180 3 girl 176 209 boy 201 200
六、多级索引轴向转换
-
常见的数据层次化结构:树状和表格
- 轴向转换的函数
-
stack()
: 将行索引变成列索引,可以理解为将表格数据转换为树状数据 -
unstack()
: 将列索引变成行索引,可以理解为将树状数据转换为表格数据 - 两个函数互为逆函数,作用相反,用法相同。单级索引时,结果会生成一个Series;多级索引时默认转换最内层索引,也可以自定义转换的索引层级
-
- 示例
print(df) # 数据源 ------------------------------------------------------------------------------------- Language English Chinese Pass Y N Y N Class Six 1 girl 86 99 111 105 boy 85 110 113 112 2 girl 98 106 108 94 boy 117 80 97 83 3 girl 95 81 114 95 boy 106 95 119 81 df.stack() # 默认将最内层的行索引(Pass)转换为了列索引 ------------------------------------------------------------------------------------- Language Chinese English Class Six Pass 1 girl N 105 99 Y 111 86 boy N 112 110 Y 113 85 2 girl N 94 106 Y 108 98 boy N 83 80 Y 97 117 3 girl N 95 81 Y 114 95 boy N 81 95 Y 119 106 df.unstack(level=0) # 指定将列索引(Class)转化成行索引 ------------------------------------------------------------------------------------- Language English Chinese Pass Y N Y N Class 1 2 3 1 2 3 1 2 3 1 2 3 Six boy 85 117 106 110 80 95 113 97 119 112 83 81 girl 86 98 95 99 106 81 111 108 114 105 94 95
七、多级索引转换单级索引
- 步骤:先将多级的行索引转换为列索引,再重置列索引
- 示例
dt = df.stack() # 将内层行索引()转换为列索引 dt = dt.reset_index() # 重置列索引 print(dt) ------------------------------------------------------------------------------------- Language Class Six Pass Chinese English 0 1 girl N 105 99 1 1 girl Y 111 86 2 1 boy N 112 110 3 1 boy Y 113 85 4 2 girl N 94 106 5 2 girl Y 108 98 6 2 boy N 83 80 7 2 boy Y 97 117 8 3 girl N 95 81 9 3 girl Y 114 95 10 3 boy N 81 95 11 3 boy Y 119 106