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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM