层次化索引(hierarchical indexing)使你能够在一个轴上拥有两个或多个索引级别,它能使你以低纬度形式处理高纬度的数据。
创建Series,并用由列表或数组组成的列表作为索引
data = Series(np.random.randn(10),
index=[['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'd', 'd'],
[1, 2, 3, 1, 2, 3, 1, 2, 2, 3]])
a 1 0.670216
2 0.852965
3 -0.955869
b 1 -0.023493
2 -2.304234
3 -0.652469
c 1 -1.218302
2 -1.332610
d 2 1.074623
3 0.723642
dtype: float64
查看索引
data.index
MultiIndex(levels=[['a', 'b', 'c', 'd'], [1, 2, 3]],
labels=[[0, 0, 0, 1, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 1, 2]])
选取数据子集
data['b']
1 -0.023493
2 -2.304234
3 -0.652469
dtype: float64
通过切片选取数据子集
data['b':'c']
通过ix选取数据子集
data.ix[['b', 'd']]
选取内层的数据子集
data[:, 2]
a 0.852965
b -2.304234
c -1.332610
d 1.074623
dtype: float64
层次化索引在数据重塑和基于分组的操作(如透视表生成)中扮演重要角色。
比如,上面数据通过unstack方法重新安排到DataFrame
data.unstack()
1 2 3
a 0.670216 0.852965 -0.955869
b -0.023493 -2.304234 -0.652469
c -1.218302 -1.332610 NaN
d NaN 1.074623 0.723642
unstack的逆运算是stack
data.unstack().stack()
对于每个DataFrame,每条轴都可以分层索引
frame = DataFrame(np.arange(12).reshape((4, 3)),
index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
columns=[['Ohio', 'Ohio', 'Colorado'],
['Green', 'Red', 'Green']])
Ohio Colorado
Green Red Green
a 1 0 1 2
2 3 4 5
b 1 6 7 8
2 9 10 11
为它们指定名字
frame.index.names = ['key1', 'key2']
frame.columns.names = ['state', 'color']
frame
选取列分组
frame['Ohio']
重排分级顺序
frame.swaplevel('key1', 'key2')
而sortlevel则根据单个级别中的值对数据进行排序
frame.sortlevel(1)
frame.swaplevel(0, 1).sortlevel(0)
根据级别汇总统计
frame.sum(level='key2')
frame.sum(level='color', axis=1)
使用DataFrame的列
frame = DataFrame({'a': range(7), 'b': range(7, 0, -1),
'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'],
'd': [0, 1, 2, 0, 1, 2, 3]})
frame
DataFrame的set_index可以将一个或多个列转换为行索引,并创建新的DataFrame
frame2 = frame.set_index(['c', 'd'])
frame2
默认,那些列会从DataFrame移除,但也可以将其保留下来
frame.set_index(['c', 'd'], drop=False)
reset_index可以将层次化索引的级别转移到列
frame2.reset_index()