pandas--层次化索引

层次化索引是pandas的一项重要功能,它使你能在一个轴上拥有多个(两个以上)索引级别。
创建一个Series,并用一个由列表或数组组成的列表作为索引。
 1 data=Series(np.random.randn(10),
 2 index=[['a','a','a','b','b','b','c','c','d','d'],
 3 [1,2,3,1,2,3,1,2,2,3]])
 4 
 5 data
 6 Out[6]: 
 7 a  1   -2.842857
 8    2    0.376199
 9    3   -0.512978
10 b  1    0.225243
11    2   -1.242407
12    3   -0.663188
13 c  1   -0.149269
14    2   -1.079174
15 d  2   -0.952380
16    3   -1.113689
17 dtype: float64

这就是带MultiIndex索引的Series的格式化输出形式。索引之间的“间隔”表示“直接使用上面的标签”。

1 data.index
2 Out[7]: 
3 MultiIndex(levels=[['a', 'b', 'c', 'd'], [1, 2, 3]],
4            labels=[[0, 0, 0, 1, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 1, 2]])

对于一个层次化索引的对象,选取数据子集的操作很简单:

 1 data['b']
 2 Out[8]: 
 3 1    0.225243
 4 2   -1.242407
 5 3   -0.663188
 6 dtype: float64
 7 
 8 
 9 data['b':'c']
10 Out[10]: 
11 b  1    0.225243
12    2   -1.242407
13    3   -0.663188
14 c  1   -0.149269
15    2   -1.079174
16 dtype: float64
17 
18 data.ix[['b','d']]
19 __main__:1: DeprecationWarning: 
20 .ix is deprecated. Please use
21 .loc for label based indexing or
22 .iloc for positional indexing
23 
24 See the documentation here:
25 http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated
26 Out[11]: 
27 b  1    0.225243
28    2   -1.242407
29    3   -0.663188
30 d  2   -0.952380
31    3   -1.113689
32 dtype: float64

甚至可以在“内层”中进行选取:

1 data[:,2]
2 Out[12]: 
3 a    0.376199
4 b   -1.242407
5 c   -1.079174
6 d   -0.952380
7 dtype: float64
 
层次化索引在数据重塑和基于分组的操作中扮演重要角色。
可以通过unstack方法被重新安排到一个DataFrame中:
 1 data.unstack()
 2 Out[13]: 
 3           1         2         3
 4 a -2.842857  0.376199 -0.512978
 5 b  0.225243 -1.242407 -0.663188
 6 c -0.149269 -1.079174       NaN
 7 d       NaN -0.952380 -1.113689
 8 
 9 
10 #unstack的逆运算是stack
11 data.unstack().stack()
12 Out[14]: 
13 a  1   -2.842857
14    2    0.376199
15    3   -0.512978
16 b  1    0.225243
17    2   -1.242407
18    3   -0.663188
19 c  1   -0.149269
20    2   -1.079174
21 d  2   -0.952380
22    3   -1.113689
23 dtype: float64

对于DataFrame,每条轴都可以有分层索引:

 1 frame=DataFrame(np.arange(12).reshape((4,3)),
 2 index=[['a','a','b','b'],[1,2,1,2]],
 3 columns=[['Ohio','Ohio','Colorado'],
 4 ['Green','Red','Green']])
 5 
 6 frame
 7 Out[16]: 
 8      Ohio     Colorado
 9     Green Red    Green
10 a 1     0   1        2
11   2     3   4        5
12 b 1     6   7        8
13   2     9  10       11

各层都可以有名字。如果指定了名称,它们会显示在控制台中(不要将索引名称和轴标签混为一谈!)

 1 frame.index.names=['key1','key2']
 2 frame.columns.names=['state','color']
 3 
 4 frame
 5 Out[22]: 
 6 state      Ohio     Colorado
 7 color     Green Red    Green
 8 key1 key2                   
 9 a    1        0   1        2
10      2        3   4        5
11 b    1        6   7        8
12      2        9  10       11

由于有了分部的列索引,可以轻松选取列分组:

1 frame['Ohio']
2 Out[23]: 
3 color      Green  Red
4 key1 key2            
5 a    1         0    1
6      2         3    4
7 b    1         6    7
8      2         9   10
 
重排分级排序
有时需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化):
1 frame.swaplevel('key1','key2')
2 Out[24]: 
3 state      Ohio     Colorado
4 color     Green Red    Green
5 key2 key1                   
6 1    a        0   1        2
7 2    a        3   4        5
8 1    b        6   7        8
9 2    b        9  10       11

sortlevel则根据单个级别中的值对数据进行排序。交换级别时,常用得到sortlevel,这样最终结果也是有序的了:

 1 frame.swaplevel(0,1)
 2 Out[27]: 
 3 state      Ohio     Colorado
 4 color     Green Red    Green
 5 key2 key1                   
 6 1    a        0   1        2
 7 2    a        3   4        5
 8 1    b        6   7        8
 9 2    b        9  10       11
10 
11 #交换级别0,1(也就是key1,key2)
12 #然后对axis=0进行排序
13 frame.swaplevel(0,1).sortlevel(0)
14 __main__:1: FutureWarning: sortlevel is deprecated, use sort_index(level= ...)
15 Out[28]: 
16 state      Ohio     Colorado
17 color     Green Red    Green
18 key2 key1                   
19 1    a        0   1        2
20      b        6   7        8
21 2    a        3   4        5
22      b        9  10       11
 
 
根据级别汇总统计
有时需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化):
 1 frame.sum(level='key2')
 2 Out[29]: 
 3 state  Ohio     Colorado
 4 color Green Red    Green
 5 key2                    
 6 1         6   8       10
 7 2        12  14       16
 8 
 9 frame.sum(level='color',axis=1)
10 Out[30]: 
11 color      Green  Red
12 key1 key2            
13 a    1         2    1
14      2         8    4
15 b    1        14    7
16      2        20   10

 

使用DataFrame的列
将DataFrame的一个或多个列当做行索引来用,或将行索引变成Dataframe 的列。
 1 frame=DataFrame({'a':range(7),'b':range(7,0,-1),
 2 'c':['one','one','one','two','two','two','two'],
 3 'd':[0,1,2,0,1,2,3]})
 4 
 5 frame
 6 Out[32]: 
 7    a  b    c  d
 8 0  0  7  one  0
 9 1  1  6  one  1
10 2  2  5  one  2
11 3  3  4  two  0
12 4  4  3  two  1
13 5  5  2  two  2
14 6  6  1  two  3

DataFrame的set_index函数会将其一个或多个列转换为行索引,并创建一个新的DataFrame:

 1 frame2=frame.set_index(['c','d'])
 2 
 3 frame2
 4 Out[34]: 
 5        a  b
 6 c   d      
 7 one 0  0  7
 8     1  1  6
 9     2  2  5
10 two 0  3  4
11     1  4  3
12     2  5  2
13     3  6  1

默认情况下,那些列会从DataFrame中移除,但也可以将其保留下来:

 1 frame.set_index(['c','d'],drop=False)
 2 Out[35]: 
 3        a  b    c  d
 4 c   d              
 5 one 0  0  7  one  0
 6     1  1  6  one  1
 7     2  2  5  one  2
 8 two 0  3  4  two  0
 9     1  4  3  two  1
10     2  5  2  two  2
11     3  6  1  two  3

reset_index的功能和set_index刚好相反,层次化索引的级别会被转移到列里面:

 1 frame2.reset_index()
 2 Out[36]: 
 3      c  d  a  b
 4 0  one  0  0  7
 5 1  one  1  1  6
 6 2  one  2  2  5
 7 3  two  0  3  4
 8 4  two  1  4  3
 9 5  two  2  5  2
10 6  two  3  6  1

 

posted @ 2018-07-18 16:17  平淡才是真~~  阅读(4203)  评论(0编辑  收藏  举报