层次化索引是pandas的一项重要功能,它使你能在一个轴上拥有多个(两个以上)索引级别。
创建一个Series,并用一个由列表或数组组成的列表作为索引。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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 ]])
data
Out[ 6 ]:
a 1 - 2.842857
2 0.376199
3 - 0.512978
b 1 0.225243
2 - 1.242407
3 - 0.663188
c 1 - 0.149269
2 - 1.079174
d 2 - 0.952380
3 - 1.113689
dtype: float64
|
这就是带MultiIndex索引的Series的格式化输出形式。索引之间的“间隔”表示“直接使用上面的标签”。
1
2
3
4
|
data.index
Out[ 7 ]:
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 ]])
|
对于一个层次化索引的对象,选取数据子集的操作很简单:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
data[ 'b' ]
Out[ 8 ]:
1 0.225243
2 - 1.242407
3 - 0.663188
dtype: float64
data[ 'b' : 'c' ]
Out[ 10 ]:
b 1 0.225243
2 - 1.242407
3 - 0.663188
c 1 - 0.149269
2 - 1.079174
dtype: float64
data.ix[[ 'b' , 'd' ]]
__main__: 1 : DeprecationWarning:
.ix is deprecated. Please use
.loc for label based indexing or
.iloc for positional indexing
See the documentation here:
http: / / pandas.pydata.org / pandas - docs / stable / indexing.html #ix-indexer-is-deprecated
Out[ 11 ]:
b 1 0.225243
2 - 1.242407
3 - 0.663188
d 2 - 0.952380
3 - 1.113689
dtype: float64
|
甚至可以在“内层”中进行选取:
1
2
3
4
5
6
7
|
data[:, 2 ]
Out[ 12 ]:
a 0.376199
b - 1.242407
c - 1.079174
d - 0.952380
dtype: float64
|
层次化索引在数据重塑和基于分组的操作中扮演重要角色。
可以通过unstack方法被重新安排到一个DataFrame中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
data.unstack()
Out[ 13 ]:
1 2 3
a - 2.842857 0.376199 - 0.512978
b 0.225243 - 1.242407 - 0.663188
c - 0.149269 - 1.079174 NaN
d NaN - 0.952380 - 1.113689
#unstack的逆运算是stack
data.unstack().stack()
Out[ 14 ]:
a 1 - 2.842857
2 0.376199
3 - 0.512978
b 1 0.225243
2 - 1.242407
3 - 0.663188
c 1 - 0.149269
2 - 1.079174
d 2 - 0.952380
3 - 1.113689
dtype: float64
|
对于DataFrame,每条轴都可以有分层索引:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
frame = DataFrame(np.arange( 12 ).reshape(( 4 , 3 )),
index = [[ 'a' , 'a' , 'b' , 'b' ],[ 1 , 2 , 1 , 2 ]],
columns = [[ 'Ohio' , 'Ohio' , 'Colorado' ],
[ 'Green' , 'Red' , 'Green' ]])
frame
Out[ 16 ]:
Ohio Colorado
Green Red Green
a 1 0 1 2
2 3 4 5
b 1 6 7 8
2 9 10 11
|
各层都可以有名字。如果指定了名称,它们会显示在控制台中(不要将索引名称和轴标签混为一谈!)
1
2
3
4
5
6
7
8
9
10
11
12
|
frame.index.names = [ 'key1' , 'key2' ]
frame.columns.names = [ 'state' , 'color' ]
frame
Out[ 22 ]:
state Ohio Colorado
color Green Red Green
key1 key2
a 1 0 1 2
2 3 4 5
b 1 6 7 8
2 9 10 11
|
由于有了分部的列索引,可以轻松选取列分组:
1
2
3
4
5
6
7
8
|
frame[ 'Ohio' ]
Out[ 23 ]:
color Green Red
key1 key2
a 1 0 1
2 3 4
b 1 6 7
2 9 10
|
重排分级排序
有时需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化):
1
2
3
4
5
6
7
8
9
|
frame.swaplevel( 'key1' , 'key2' )
Out[ 24 ]:
state Ohio Colorado
color Green Red Green
key2 key1
1 a 0 1 2
2 a 3 4 5
1 b 6 7 8
2 b 9 10 11
|
sortlevel则根据单个级别中的值对数据进行排序。交换级别时,常用得到sortlevel,这样最终结果也是有序的了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
frame.swaplevel( 0 , 1 )
Out[ 27 ]:
state Ohio Colorado
color Green Red Green
key2 key1
1 a 0 1 2
2 a 3 4 5
1 b 6 7 8
2 b 9 10 11
#交换级别0,1(也就是key1,key2)
#然后对axis=0进行排序
frame.swaplevel( 0 , 1 ).sortlevel( 0 )
__main__: 1 : FutureWarning: sortlevel is deprecated, use sort_index(level = ...)
Out[ 28 ]:
state Ohio Colorado
color Green Red Green
key2 key1
1 a 0 1 2
b 6 7 8
2 a 3 4 5
b 9 10 11
|
根据级别汇总统计
有时需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
frame. sum (level = 'key2' )
Out[ 29 ]:
state Ohio Colorado
color Green Red Green
key2
1 6 8 10
2 12 14 16
frame. sum (level = 'color' ,axis = 1 )
Out[ 30 ]:
color Green Red
key1 key2
a 1 2 1
2 8 4
b 1 14 7
2 20 10
|
使用DataFrame的列
将DataFrame的一个或多个列当做行索引来用,或将行索引变成Dataframe 的列。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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
Out[ 32 ]:
a b c d
0 0 7 one 0
1 1 6 one 1
2 2 5 one 2
3 3 4 two 0
4 4 3 two 1
5 5 2 two 2
6 6 1 two 3
|
DataFrame的set_index函数会将其一个或多个列转换为行索引,并创建一个新的DataFrame:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
frame2 = frame.set_index([ 'c' , 'd' ])
frame2
Out[ 34 ]:
a b
c d
one 0 0 7
1 1 6
2 2 5
two 0 3 4
1 4 3
2 5 2
3 6 1
|
默认情况下,那些列会从DataFrame中移除,但也可以将其保留下来:
1
2
3
4
5
6
7
8
9
10
11
|
frame.set_index([ 'c' , 'd' ],drop = False )
Out[ 35 ]:
a b c d
c d
one 0 0 7 one 0
1 1 6 one 1
2 2 5 one 2
two 0 3 4 two 0
1 4 3 two 1
2 5 2 two 2
3 6 1 two 3
|
reset_index的功能和set_index刚好相反,层次化索引的级别会被转移到列里面:
1
2
3
4
5
6
7
8
9
10
|
frame2.reset_index()
Out[ 36 ]:
c d a b
0 one 0 0 7
1 one 1 1 6
2 one 2 2 5
3 two 0 3 4
4 two 1 4 3
5 two 2 5 2
6 two 3 6 1
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://www.cnblogs.com/dataAnalysis/p/9329827.html