索引對象
pandas的索引對象負責管理軸標簽和其他元數據(比如軸名稱等)。構建series或DataFrame時,所用到的任何數組或其他序列的標簽都會轉換成一個index:
In [1]: import pandas as pd In [2]: import numpy as np In [3]: from pandas import Series In [4]: obj=Series(range(3),index=['a','b','c']) In [5]: index=obj.index In [6]: index Out[6]: Index(['a', 'b', 'c'], dtype='object') In [7]: index[1:] Out[7]: Index(['b', 'c'], dtype='object')
index對象是不可修改的(immutable),因此用戶不能對其進行修改
In [8]: index[1]='d' --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-8-8be6e68dba2d> in <module>() ----> 1 index[1]='d' d:\python\python36\lib\site-packages\pandas\core\indexes\base.py in __setitem__(self, key, value) 2048 2049 def __setitem__(self, key, value): -> 2050 raise TypeError("Index does not support mutable operations") 2051 2052 def __getitem__(self, key): TypeError: Index does not support mutable operations
不可修改性非常重要,因為這樣才能使Index對象在多個數據結構之間安全共享:
In [9]: index=pd.Index(np.arange(3)) In [10]: obj2=Series([1.5,-2.5,0],index=index) In [11]: obj2.index is index Out[11]: True In [12]: obj2.index Out[12]: Int64Index([0, 1, 2], dtype='int64')
Index類為pandas庫中內置的類。
pandas中主要的index對象:
1.index 最泛化的Index對象,將軸標簽表示為一個由python對象組成的Numpy數組
2.Int64Index 針對整數的特殊Index
3.MultilIndex “層次化”索引對象,表示單個軸上的多層索引。可以看做由元組組成的數組。
4.DatatimeIndex 存儲納秒級時間戳(用Numpy的datatime64類型表示)
5.PeriodIndex 針對Period數據(時間間隔)的特殊Index
Index的方法和屬性
append 連接另一個Index對象,產生一個新的Index
diff 計算差集,並得到一個Index
intersection 計算交集
union 計算並集
isin 計算一個指示各值是否都包含在參數集合那種的布爾型數組
delete 刪除索引i處的元素,並得到一個新的Index
drop 刪除傳入的值,並得到新的Index
insert 將元素插入到索引i處,並得到一個新的Index
is_monotonic 當各元素均大於等於前一個元素時,返回True
is_unique 當Index沒有重復值時,返回True
unique 計算Index中唯一值的數組
重新索引
pandas對象的一個重要方法是reindex,其作用是創建一個適應新索引的新對象。
In [16]: obj=Series([4.5,7.3,-5.3,3.6],index=['d','b','a','c']) In [17]: obj Out[17]: d 4.5 b 7.3 a -5.3 c 3.6 dtype: float64
調用該Series的reindex將會根據新索引進行重排。如果當某個索引值當前不存在,就引入缺失值:
In [18]: obj2=obj.reindex(['a','b','c','d','e']) In [19]: obj2 Out[19]: a -5.3 b 7.3 c 3.6 d 4.5 e NaN dtype: float64
In [22]: obj.reindex(['a','b','c','d','e'],fill_value=0) Out[22]: a -5.3 b 7.3 c 3.6 d 4.5 e 0.0 dtype: float64
對於時間序列這樣的有序數據,重新索引可能需要做一些插值處理。method選項可以達到這個目的。
使用ffill可以實現前向值填充:
In [23]: obj3=Series(['blue','purple','yellow'],index=[0,2,4]) In [24]: obj3.reindex(range(6),method='ffill') Out[24]: 0 blue 1 blue 2 purple 3 purple 4 yellow 5 yellow dtype: object
reindex的(插值)method選項:
ffill 或pad 前向填充(或搬運)值
bfill 或backfill 后向填充(或搬運)值
對於DataFrame,reindex可以修改(行)索引 丶列,或2個都修改。如果僅傳入一個序列,則會重新索引行:
In [26]: from pandas import DataFrame In [27]: frame = DataFrame(np.arange(9).reshape((3,3)),index=['a','c','d'],columns=['Ohio','Texas','California']) In [28]: frame Out[28]: Ohio Texas California a 0 1 2 c 3 4 5 d 6 7 8 In [29]: frame2=frame.reindex(['a','b','c','d']) In [30]: frame2 Out[30]: Ohio Texas California a 0.0 1.0 2.0 b NaN NaN NaN c 3.0 4.0 5.0 d 6.0 7.0 8.0
使用columns關鍵字可以重新索引列:
In [31]: states=['Texas','Utah','California'] In [32]: frame.reindex(columns=states) Out[32]: Texas Utah California a 1 NaN 2 c 4 NaN 5 d 7 NaN 8
也可以同時對行和列進行重新索引,而插值則只能按行應用:
In [44]: frame.reindex(index=['a','b','c','d'],method='ffill') Out[44]: Ohio Texas California a 0 1 2 b 0 1 2 c 3 4 5 d 6 7 8
In [46]: frame.reindex(index=['a','b','c','d'],method='ffill').reindex(columns=states) Out[46]: Texas Utah California a 1 NaN 2 b 1 NaN 2 c 4 NaN 5 d 7 NaN 8
利用ix的標簽索引功能,重新索引任務可以變得更簡潔:
In [54]: frame.ix[['a','b','c','d'],states] Out[54]: Texas Utah California a 1.0 NaN 2.0 b NaN NaN NaN c 4.0 NaN 5.0 d 7.0 NaN 8.0
reindex函數的參數:
index:作為索引的新序列。既可以是index實例也可以是其他序列型的python數據結構。index會被完全使用,就像沒有任何復制一樣。
method:插值(填充)方式,參數(fill丶pad丶bfill丶backfill)
fill_value:在重新索引的過程中,需要引入缺失值使用的任何替代值。
limit:前向或后向填充時的最大填充量。
level:在MultiIndex的指定級別上匹配簡單索引,否則選取子集。
copy:默認為True,無論如何都復制;如果為false,則新舊相等就不復制。
丟棄指定軸上的項
丟棄某條軸上的一個或多個項很簡單,只要有一個索引數組或列表即可。由於需要執行一些數據整理和集合邏輯,所以drop方法返回的是一個在指定軸上刪除了指定值的新對象:
In [13]: obj=Series(np.arange(5.),index=['a','b','c','d','e']) In [14]: new_obj=obj.drop('c') In [15]: new_obj Out[15]: a 0.0 b 1.0 d 3.0 e 4.0 dtype: float64 In [16]: obj.drop(['d','c']) Out[16]: a 0.0 b 1.0 e 4.0 dtype: float64 In [17]: obj Out[17]: a 0.0 b 1.0 c 2.0 d 3.0 e 4.0 dtype: float64
注意:drop后返回的是一個新的對象,原始的不改變。
對於DataFrame,可以刪除任意軸上的索引值:
In [19]: data=DataFrame(np.arange(16).reshape((4,4)),index=['a','b','c','d'],columns=['1','2','3','4']) In [20]: data Out[20]: 1 2 3 4 a 0 1 2 3 b 4 5 6 7 c 8 9 10 11 d 12 13 14 15 In [21]: data.drop(['a','c']) Out[21]: 1 2 3 4 b 4 5 6 7 d 12 13 14 15 In [22]: data.drop('2',axis=1) Out[22]: 1 3 4 a 0 2 3 b 4 6 7 c 8 10 11 d 12 14 15
In [28]: data.drop(['1','3'],axis=1)
Out[28]:
2 4
a 1 3
b 5 7
c 9 11
d 13 15
索引丶選取和過濾
Series索引的工作方式類似於NumPy數組的索引,只不過Series索引值不只是整數。
In [29]: obj=Series(np.arange(5),index=['a','b','c','d','e']) In [30]: obj Out[30]: a 0 b 1 c 2 d 3 e 4 dtype: int32 In [31]: obj['b'] Out[31]: 1 In [32]: obj[1] Out[32]: 1 In [33]: obj[2:4] Out[33]: c 2 d 3 dtype: int32 In [34]: obj[obj<2] Out[34]: a 0 b 1 dtype: int32 In [35]: obj[['a','c','d']] Out[35]: a 0 c 2 d 3 dtype: int32 In [36]: obj[[1,3,4]] Out[36]: b 1 d 3 e 4 dtype: int32
利用標簽的切片運算與普通的python切片運算不同,末端是包含的封閉區間。
In [37]: obj[['a','c']] Out[37]: a 0 c 2 dtype: int32
設置的方式也很簡單:
In [38]: obj Out[38]: a 0 b 1 c 2 d 3 e 4 dtype: int32 In [39]: obj[['a','c']]=6 In [40]: obj Out[40]: a 6 b 1 c 6 d 3 e 4 dtype: int32
對DataFrame索引就是獲取一個或多個列:
In [41]: data Out[41]: 1 2 3 4 a 0 1 2 3 b 4 5 6 7 c 8 9 10 11 d 12 13 14 15 In [42]: data['1'] Out[42]: a 0 b 4 c 8 d 12 Name: 1, dtype: int32 In [43]: data[['1','3']] Out[43]: 1 3 a 0 2 b 4 6 c 8 10 d 12 14
這種索引方式有幾個特殊的情況。首先通過切片或布爾型數組選取行:
In [44]: data[:2] Out[44]: 1 2 3 4 a 0 1 2 3 b 4 5 6 7 In [45]: data[data['2']>5] Out[45]: 1 2 3 4 c 8 9 10 11 d 12 13 14 15
另一種用法是通過布爾型DataFrame進行索引:
In [46]: data<5 Out[46]: 1 2 3 4 a True True True True b True False False False c False False False False d False False False False In [47]: data[data<5] Out[47]: 1 2 3 4 a 0.0 1.0 2.0 3.0 b 4.0 NaN NaN NaN c NaN NaN NaN NaN d NaN NaN NaN NaN
這段代碼的目的是使DataFrame在語法上更像ndarry。