pandas對象的一個重要反覆是reindex,其做用是建立一個適應新索引的新對象。數組
In [136]: obj=Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c']) In [137]: obj2=obj.reindex(['a','b','c','d','e']) In [138]: obj2 Out[138]: a -5.3 b 7.2 c 3.6 d 4.5 e NaN dtype: float64
若是某個索引值不存在,就引入缺失值數據結構
In [140]: obj.reindex(['a','b','c','d','e'],fill_value=0) Out[140]: a -5.3 b 7.2 c 3.6 d 4.5 e 0.0 dtype: float64
對於時間序列這樣的有序數據,從新索引時可能須要作一些插值處理,method選項便可達到目的app
In [141]: obj3=Series(['blue','purple','yellow'],index=[0,2,4]) In [142]: obj3.reindex(range(6),method='ffill') Out[142]: 0 blue 1 blue 2 purple 3 purple 4 yellow 5 yellow dtype: object
reindex的(插值) method選項dom
fill或pad:前向填充(或搬運)值ide
bfill或backfill:後向填充(或搬運)值函數
對於DataFrame,reindex能夠修改(行)索引、列,或2個都修改,若是隻傳入一個序列,則從新索引行spa
In [143]: frame=DataFrame(np.arange(9).reshape(3,3),index=['a','b','c'],columns=['one','two','three']) ...: In [144]: frame Out[144]: one two three a 0 1 2 b 3 4 5 c 6 7 8 In [145]: frame2=frame.reindex(['a','b','c','d']) In [146]: frame2 Out[146]: one two three a 0.0 1.0 2.0 b 3.0 4.0 5.0 c 6.0 7.0 8.0 d NaN NaN NaN In [147]: states=['red','yellow','green'] In [148]: frame.reindex(columns=states) Out[148]: red yellow green a NaN NaN NaN b NaN NaN NaN c NaN NaN NaN In [149]: states=['red','one','two'] In [150]: frame.reindex(columns=states) Out[150]: red one two a NaN 0 1 b NaN 3 4 c NaN 6 7
也能夠同時對行和列進行從新索引,而插值則只能按行應用code
In [158]: frame.reindex(index=['a','b','c','d'],method='ffill',columns=['one','two','three']) Out[158]: one two three a 0 1 2 b 3 4 5 c 6 7 8 d 6 7 8
利用ix的標籤索引功能,從新索引任務能夠變得簡潔。對象
reindex函數的參數:blog
index:用做索引的新序列。既能夠是index實例,也能夠是其餘序列型的Python數據結構。index會被徹底使用,就像沒有任何複製同樣。
method:插值(填充)方式
fill_value:在從新索引過程當中,須要填入缺失值時使用的替代值
limit:前向填充或後向填充的最大填充量
level:在MultiIndex的指定級別上匹配簡單索引,不然取其子集
copy:默認爲true,不管如何都複製,若是爲False,則新舊相等就不復制
丟棄某條軸上的一個或多個項很簡單,只須要有一個索引數組或列表便可。
In [162]: obj=Series(np.arange(5.),index=['a','b','c','d','e']) In [163]: new_obj=obj.drop('c') In [164]: new_obj Out[164]: a 0.0 b 1.0 d 3.0 e 4.0 dtype: float64 In [165]: obj Out[165]: a 0.0 b 1.0 c 2.0 d 3.0 e 4.0 dtype: float64
對於DataFrame,能夠任意刪除任意軸上的索引值:
In [166]: data=DataFrame(np.arange(16).reshape(4,4),index=['Ohio','Colorado','Utah','New York'],column ...: s=['one','two','three','four']) In [167]: data.drop(['Colorado','Ohio']) Out[167]: one two three four Utah 8 9 10 11 New York 12 13 14 15
In [170]: data.drop('two',axis=1)
Out[170]:
one three four
Ohio 0 2 3
Colorado 4 6 7
Utah 8 10 11
New York 12 14 15
In [171]: data.drop(['two','four'],axis=1)
Out[171]:
one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14
Series索引的工做方式相似於numpy數組的索引,只不過Series的索引值不僅是整數
In [173]: obj=Series(np.arange(4.),index=['a','b','c','d']) In [174]: obj['a'] Out[174]: 0.0 In [175]: obj[1] Out[175]: 1.0 In [176]: obj[['b','a','d']] Out[176]: b 1.0 a 0.0 d 3.0 dtype: float64 In [177]: obj[obj<2] Out[177]: a 0.0 b 1.0 dtype: float64
利用標籤的切片運算和普通的Python切片運算不一樣,其末端是包含的:
In [180]: obj['b':'c'] Out[180]: b 1.0 c 2.0 dtype: float64
In [181]: obj[2:3]
Out[181]:
c 2.0
dtype: float64
設置的方式也很簡單:
In [182]: obj['b':'c']=5 In [183]: obj Out[183]: a 0.0 b 5.0 c 5.0 d 3.0 dtype: float64
DataFrame進行索引就是獲取一個或多個列:
In [184]: data Out[184]: one two three four Ohio 0 1 2 3 Colorado 4 5 6 7 Utah 8 9 10 11 New York 12 13 14 15 In [185]: data['one'] Out[185]: Ohio 0 Colorado 4 Utah 8 New York 12 Name: one, dtype: int32
這種索引方式有幾個特殊狀況。首先經過切片或布爾型數組進行取行:
In [187]: data[:2] Out[187]: one two three four Ohio 0 1 2 3 Colorado 4 5 6 7 In [188]: data[data['three']>5] Out[188]: one two three four Colorado 4 5 6 7 Utah 8 9 10 11 New York 12 13 14 15
另外一種是經過布爾型DataFrame進行索引:
In [189]: data<5 Out[189]: one two three four Ohio True True True True Colorado True False False False Utah False False False False New York False False False False In [190]: data[data<5]=0 In [191]: data Out[191]: one two three four Ohio 0 0 0 0 Colorado 0 5 6 7 Utah 8 9 10 11 New York 12 13 14 15
經過索引字段ix選取行和列的子集:
In [197]: data.ix['Colorado',['two','three']] Out[197]: two 5 three 6 Name: Colorado, dtype: int32
DataFrame的索引選項:
類型:說明
obj[val] : 選取DataFrame的單個列或一組列。在一些特殊狀況下會比較便利;布爾型數組、切片、布爾型DataFrame
obj.ix[val]:選取DataFrame的單個行或一組行
obj.ix[:,val]:選取單個列或列子集
obj.ix[val1,val2]:同時選取行和列
reindex方法:將一個或多個軸匹配到新索引
xs方法:根據標籤選取單行或單列,並返回一個Series
icol、irow方法:根據整數位置選取單列或單行,並返回一個Series
get_value、set_value方法:根據行標籤或列標籤選取單個值。
pandas最重要的一個功能是,它能夠對不一樣索引的對象進行算術運算。在將對象相加時,若是存在不一樣的索引對,則結果的索引就是該索引對的並集。
In [7]: s1=Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e']) In [8]: s2=Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g']) In [9]: s1+s2 Out[9]: a 5.2 c 1.1 d NaN e 0.0 f NaN g NaN dtype: float64
自動的數據對齊操做不重疊的索引處引入了NA值。缺失值會在算術運算中傳播。
對於DataFrame,對齊操做會同時發生在行和列上:
In [15]: df1=DataFrame(np.arange(9).reshape(3,3),columns=list('bcd'),index=['one','two','three']) In [16]: df2=DataFrame(np.arange(12).reshape(4,3),columns=list('bde'),index=['one','two','three','four']) In [17]: df1+df2 Out[17]: b c d e four NaN NaN NaN NaN one 0.0 NaN 3.0 NaN three 12.0 NaN 15.0 NaN two 6.0 NaN 9.0 NaN
在對不一樣的索引對象進行算術運算時,可能但願當一個對象中某個軸標籤在另外一個對象中找不到時,填充一個特殊值:
In [18]: df1=DataFrame(np.arange(12).reshape(3,4),columns=list('abcd')) In [19]: df2=DataFrame(np.arange(20).reshape(4,5),columns=list('abcde')) In [20]: df1+df2 Out[20]: a b c d e 0 0.0 2.0 4.0 6.0 NaN 1 9.0 11.0 13.0 15.0 NaN 2 18.0 20.0 22.0 24.0 NaN 3 NaN NaN NaN NaN NaN
使用df1的add方法,傳入df2以及一個fill_value參數:
In [21]: df1.add(df2,fill_value=0) Out[21]: a b c d e 0 0.0 2.0 4.0 6.0 4.0 1 9.0 11.0 13.0 15.0 9.0 2 18.0 20.0 22.0 24.0 14.0 3 15.0 16.0 17.0 18.0 19.0
與此相似,在對Series或DataFrame從新索引時,也能夠指定一個填充值:
In [22]: df1.reindex(columns=df2.columns,fill_value=0) Out[22]: a b c d e 0 0 1 2 3 0 1 4 5 6 7 0 2 8 9 10 11 0
算術方法:add(加法)、sub(減法)、div(除法)、mul(乘法)
跟numpy數組同樣,DataFrame和Series之間的算術運算也是有明確規定的
In [23]: arr=np.arange(12).reshape(3,4) In [24]: arr Out[24]: array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) In [25]: arr[0] Out[25]: array([0, 1, 2, 3]) In [26]: arr-arr[0] Out[26]: array([[0, 0, 0, 0], [4, 4, 4, 4], [8, 8, 8, 8]])
這就叫廣播。DataFrame和Series之間的運算也是如此。
In [27]: frame=DataFrame(np.arange(12).reshape(4,3),columns=list('bde'),index=['one','two','three','four']) In [28]: series=frame.ix[0] In [29]: frame Out[29]: b d e one 0 1 2 two 3 4 5 three 6 7 8 four 9 10 11 In [30]: series Out[30]: b 0 d 1 e 2 Name: one, dtype: int32
默認狀況下,DataFrame和Series之間的算術運算會將Series的索引匹配到DataFrame的列,而後沿着行一直向下廣播:
In [31]: frame-series Out[31]: b d e one 0 0 0 two 3 3 3 three 6 6 6 four 9 9 9
若是某個索引值在DataFrame的列或Series的索引中找不到,則參與運算的兩個對象就會被從新索引以造成並集:
In [32]: series2=Series(range(3),index=['b','e','f']) In [33]: frame+series2 Out[33]: b d e f one 0.0 NaN 3.0 NaN two 3.0 NaN 6.0 NaN three 6.0 NaN 9.0 NaN four 9.0 NaN 12.0 NaN
若是但願匹配行且在列上廣播,那麼必須使用算術運算方法:
In [34]: series3=frame['d'] In [35]: frame Out[35]: b d e one 0 1 2 two 3 4 5 three 6 7 8 four 9 10 11 In [36]: series3 Out[36]: one 1 two 4 three 7 four 10 Name: d, dtype: int32 In [37]: frame.sub(series3,axis=0) Out[37]: b d e one -1 0 1 two -1 0 1 three -1 0 1 four -1 0 1
numpy的ufunc(元素級數組方法)也能夠用於操做pandas對象
In [40]: frame=DataFrame(np.random.randn(4,3),columns=list('bde'),index=['one','two','three','four']) In [41]: frame Out[41]: b d e one 0.341012 0.864333 0.228682 two -0.838441 0.483385 1.747057 three 0.479806 -2.392724 0.385935 four 0.602425 -0.150350 -0.072265 In [42]: np.abs(frame) Out[42]: b d e one 0.341012 0.864333 0.228682 two 0.838441 0.483385 1.747057 three 0.479806 2.392724 0.385935 four 0.602425 0.150350 0.072265 In [43]: np.sum(frame) Out[43]: b 0.584803 d -1.195355 e 2.289409 dtype: float64
另外一個常見的操做是,將行數應用到各行或各列所造成的一維數組上。DataFrame的apply方法能夠實現功能
In [44]: f=lambda x:x.max() - x.min() In [45]: frame.apply(f) Out[45]: b 1.440866 d 3.257057 e 1.819322 dtype: float64 In [46]: frame.apply(f,axis=1) Out[46]: one 0.635651 two 2.585498 three 2.872530 four 0.752775 dtype: float64
許多常見的數組統計功能都被實現成DataFrame的方法,所以無需apply方法。
除了標量值外,傳遞給apply的函數還能夠返回由多個值組成的series:
In [49]: def f(x): ...: return Series([x.min(),x.max()],index=['min','max']) ...: ...: In [50]: frame.apply(f) Out[50]: b d e min -0.838441 -2.392724 -0.072265 max 0.602425 0.864333 1.747057
根據條件對數據集排序也是一種重要的內置運算。要對行或列索引進行排序,可以使用sort_index方法,它返回一個已排序的新對象:
In [51]: obj=Series(range(4),index=list('dabc')) In [52]: obj.sort_index() Out[52]: a 1 b 2 c 3 d 0 dtype: int64
而對於DataFrame,則能夠根據任意一個軸上的索引進行排序:
In [54]: frame Out[54]: b d e one 0.341012 0.864333 0.228682 two -0.838441 0.483385 1.747057 three 0.479806 -2.392724 0.385935 four 0.602425 -0.150350 -0.072265 In [55]: frame.sort_index() Out[55]: b d e four 0.602425 -0.150350 -0.072265 one 0.341012 0.864333 0.228682 three 0.479806 -2.392724 0.385935 two -0.838441 0.483385 1.747057 In [56]: frame.sort_index(axis=1) Out[56]: b d e one 0.341012 0.864333 0.228682 two -0.838441 0.483385 1.747057 three 0.479806 -2.392724 0.385935 four 0.602425 -0.150350 -0.072265
數據默認是按升序排序的,也能夠按照降序排序:
In [57]: frame.sort_index(axis=1,ascending=False) Out[57]: e d b one 0.228682 0.864333 0.341012 two 1.747057 0.483385 -0.838441 three 0.385935 -2.392724 0.479806 four -0.072265 -0.150350 0.602425
在DataFrame上,若是須要根據一個或多個列中的值進行排序,將一個或多個列的名字傳遞給by選項便可:
In [71]: frame=DataFrame({'b':[4,7,-2,3],'a':[0,1,0,1]}) In [72]: frame Out[72]: b a 0 4 0 1 7 1 2 -2 0 3 3 1
In [73]: frame.sort_values(by='a')
Out[73]:
b a
0 4 0
2 -2 0
1 7 1
3 3 1
In [77]: frame.sort_index(by=['a','b'])
Out[77]:
b a
2 -2 0
0 4 0
3 3 1
1 7 1
排名跟排序關係密切,且它會增設一個排名值(從1開始,一直到數組中有效數據的數量)。它跟numpy.argsort產生的間接排序索引差很少,只不過它能夠根據某種規則破壞平級關係,那就是rank方法。
rank方法是經過」爲各組分配一個平均排名「的方式破壞平級關係:
In [78]: obj=Series([7,-5,7,4,2,0,4]) In [79]: obj.rank() Out[79]: 0 6.5 1 1.0 2 6.5 3 4.5 4 3.0 5 2.0 6 4.5 dtype: float64
也能夠根據值在源數據中出現的順序給出排名:
In [80]: obj.rank(method='first') Out[80]: 0 6.0 1 1.0 2 7.0 3 4.0 4 3.0 5 2.0 6 5.0 dtype: float64
也能夠按照降序排名:
In [81]: obj.rank(method='max',ascending=False) Out[81]: 0 2.0 1 7.0 2 2.0 3 4.0 4 5.0 5 6.0 6 4.0 dtype: float64
排名用於破壞平級關係的method選項:
average:默認:在相等分組中,爲各個值分配平均排名
min:使用整個分組的最小排名
max:使用整個分組最大排名
first:按值在原始數據中出現的順序分配排名
雖然不少pandas函數都要求標籤惟一,但不是強制性的:
In [85]: obj=Series(range(5),index=list('aabbc')) In [86]: obj Out[86]: a 0 a 1 b 2 b 3 c 4 dtype: int64
索引的is_unique屬性能夠告訴你它的值是否惟一
In [87]: obj.index.is_unique
Out[87]: False
對帶有重複值的索引,數據選取的行爲將會有些不一樣。若是某個索引對應多個值,則返回一個Series,而對應單個值得,則返回一個標量:
In [88]: obj['a'] Out[88]: a 0 a 1 dtype: int64 In [89]: obj['c'] Out[89]: 4
對DataFrame的行進行索引時也是如此:
In [94]: df=DataFrame(np.arange(12).reshape(4,3),index=list('aabb')) In [95]: df.ix['b'] Out[95]: 0 1 2 b 6 7 8 b 9 10 11 In [96]: df Out[96]: 0 1 2 a 0 1 2 a 3 4 5 b 6 7 8 b 9 10 11