利用python進行數據分析之pandas入門

轉自https://zhuanlan.zhihu.com/p/26100976python

 

目錄:

5.1 pandas 的數據結構介紹
5.1.1 Series
5.1.2 DataFrame
5.1.3索引對象
5.2基本功能 
5.2.1從新索引
5.2.2丟棄指定軸上的項
5.2.3索引、選取和過濾
5.2.4算術運算和數據對齊
5.2.4.1在算術方法中填充值
5.2.4.2 DataFrame和Series之間的運算
5.2.5函數應用和映射
5.2.6排序和排名
5.2.7帶有重複的軸索引
5.3彙總和計算描述性統計
5.3.1相關係數和協方差
5.3.2惟一值、值計數以及成員資格
5.4處理缺失數據
5.4.1濾除缺失數據
5.4.2填充缺失數據
5.5層次化索引
5.5.1重排分級順序
5.5.2根據級別彙總統計
5.5.3使用DataFrame的列
5.6其餘有關pandas的話題
5.6.1整數索引



第5章 pandas入門 

pandas 引入約定

數組

In [1]: from pandas import Series,DataFrame In [2]: import pandas as pd 


5.1 pandas 的數據結構介紹

要使用pandas,首先要熟悉他的兩個主要的數據結構:Series和DataFrame。

5.1.1 Series

Series 是一種相似於一維數組的對象,由一組數據(各類numpy數據類型)以及一組與之相關的數據標籤(即索引)組成。
僅由一組數據便可產生最簡單的Series:

安全

In [3]: obj=Series([4,7,-5,3]) In [4]: obj Out[4]: 0 4 1 7 2 -5 3 3 dtype: int64 


serice 的字符串表現形式爲:索引在左邊,值在右邊。
因爲咱們沒有爲數據指定索引,因而會自動建立一個0到N-1(N位數據的長度)的整數的索引。
能夠經過series的values和index屬性獲取其數組表現形式和索引對象。

數據結構

In [6]: obj.values #表現形式 Out[6]: array([ 4, 7, -5, 3], dtype=int64) In [7]: obj.index #索引對象 Out[7]: RangeIndex(start=0, stop=4, step=1) 


一般咱們但願所建立的Series帶有一個能夠對各個數據點進行標記的索引:app

In [11]: obj2['a'] Out[11]: -5 In [12]: obj2['d']=6 In [13]: obj2[['c','a','d']] Out[13]: c 3 a -5 d 6 dtype: int64 


NumPy數組運算(若根據布爾型數組進行過濾,標量乘法,應用數學函數等)都會保留索引和值之間的連接:

dom

In [14]: obj2 Out[14]: d 6 b 7 a -5 c 3 dtype: int64 In [15]: obj2[obj2>0] Out[15]: d 6 b 7 c 3 dtype: int64 In [16]: obj2*2 Out[16]: d 12 b 14 a -10 c 6 dtype: int64 In [19]: np.exp(obj2) Out[19]: d 403.428793 b 1096.633158 a 0.006738 c 20.085537 dtype: float64 


咱們也能夠將Serice當作一個定長的有序字典,由於它是索引值到數據值的一個映射。能夠用在許多本來須要字典參數的函數中:

函數

In [20]: 'b' in obj2 Out[20]: True In [21]: 'e' in obj2 Out[21]: False 


若是數據被存放在一個python字典中,能夠直接經過這個字典來建立Series學習

In [4]: sdata={'Ohio':35000,'Texas':71000,'Oregon':16000,'Utah':5000} In [5]: obj3=Series(sdata) In [6]: obj3 Out[6]: Ohio 35000 Oregon 16000 Texas 71000 Utah 5000 dtype: int64 


只傳入一個字典,則結果Series中索引就是原字典的鍵(有序排列)spa

In [7]: states=['California','Ohio','Oregon','Texas'] In [8]: obj4=Series(sdata,index=states) In [9]: obj4 Out[9]: California NaN #「California 」的值找不到,結果用NaN來代替。 Ohio 35000.0 Oregon 16000.0 Texas 71000.0 dtype: float64 


pandas的isnull和notnull函數能夠用於檢測缺失數據:設計

In [10]: pd.isnull(obj4) Out[10]: California True Ohio False Oregon False Texas False dtype: bool In [11]: pd.notnull(obj4) Out[11]: California False Ohio True Oregon True Texas True dtype: bool 


Series也有相似的實例方法:

In [12]: obj4.isnull() Out[12]: California True Ohio False Oregon False Texas False dtype: bool 


Series重要的一個功能是:它在算術中會自動對齊不一樣索引的數據。

In [13]: obj3 Out[13]: Ohio 35000 Oregon 16000 Texas 71000 Utah 5000 dtype: int64 In [14]: obj4 Out[14]: California NaN Ohio 35000.0 Oregon 16000.0 Texas 71000.0 dtype: float64 In [15]: obj3+obj4 Out[15]: California NaN Ohio 70000.0 Oregon 32000.0 Texas 142000.0 Utah NaN dtype: float64 


Series對象自己及其索引都有一個name屬性,該屬性跟pandas其餘關鍵功能關係很是密切:

In [16]: obj4.name='population' In [17]: obj4.index.name='state' In [18]: obj4 Out[18]: state California NaN Ohio 35000.0 Oregon 16000.0 Texas 71000.0 Name: population, dtype: float64 


Series 的索引能夠經過賦值的方式就地修改:

In [20]: obj=Series([4,7,-5,3]) In [21]: obj.index=['Bob','Steve','Jeff','Ryan'] In [22]: obj Out[22]: Bob 4 Steve 7 Jeff -5 Ryan 3 dtype: int64 


5.1.2 DataFrame
DataFrame是一個表格型的數據結構,含有一組有序的列,每列能夠是不一樣的值類型(數值,字符串,布爾值等)
DataFrame既有行索引也有列索引,能夠被看作是由Series組成的字典。
跟其餘的相似的數據結構相比(如R的data.frame),DataFrame中面向行和列的操做基本是平衡的。

DataFrame中的數據是以一個或多個二維塊存放的。

構建DataFrame的辦法有不少,最經常使用的一種是直接傳入一個由等長列表或numpy組成的數組組成的字典:

In [5]: from pandas import Series,DataFrame In [6]: import pandas as pd In [7]: data={'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],'year':[2000,2001,2002,2001,2002],'pop':[1.5,1.7,3.6,2.4,2.9]} In [8]: frame=DataFrame(data) 


結果DataFrame'會自動加上索引(跟Series同樣),且所有列會被有序排列:

In [10]: frame Out[10]: pop state year 0 1.5 Ohio 2000 1 1.7 Ohio 2001 2 3.6 Ohio 2002 3 2.4 Nevada 2001 4 2.9 Nevada 2002 


指定列序列,DataFrame的列就會按照指定順序進行排列:

In [11]: DataFrame(data,columns=['year','state','pop']) Out[11]: year state pop 0 2000 Ohio 1.5 1 2001 Ohio 1.7 2 2002 Ohio 3.6 3 2001 Nevada 2.4 4 2002 Nevada 2.9 


跟Series同樣,若是傳入的列在數據中找不到,就會產生NA值:

In [11]: frame2=DataFrame(data,columns=['year','state','pop','debt'] ...: ,index=['one','two','three','four','five']) In [12]: frame2 Out[12]: year state pop debt one 2000 Ohio 1.5 NaN two 2001 Ohio 1.7 NaN three 2002 Ohio 3.6 NaN four 2001 Nevada 2.4 NaN five 2002 Nevada 2.9 NaN In [26]: frame2.columns Out[26]: Index([u'years', u'state', u'pop', u'debt'], dtype='object') 


經過相似於字典標記的方式或屬性的方式,能夠將DataFrame的列獲取爲一個Series:

In [27]: frame2['state'] Out[27]: one Ohio two Ohio three Ohio four Nevada five Nevada Name: state, dtype: object In [18]: frame2.year Out[18]: one 2000 two 2001 three 2002 four 2001 five 2002 Name: year, dtype: int64 


注意,返回的Series擁有原DataFrame相同的索引,且其name屬性也已經被相應的設置好了。
行也能夠經過位置或名稱的方式來進行獲取。

In [19]: frame2.ix['three'] Out[19]: year 2002 state Ohio pop 3.6 debt NaN Name: three, dtype: object 


列能夠經過賦值的方式進行修改。以下,咱們能夠給空的」debt「列賦值一個標量或一組值。

In [20]: frame2['debt']=16.5 In [21]: frame2 Out[21]: year state pop debt one 2000 Ohio 1.5 16.5 two 2001 Ohio 1.7 16.5 three 2002 Ohio 3.6 16.5 four 2001 Nevada 2.4 16.5 five 2002 Nevada 2.9 16.5 In [24]: frame2['debt']=np.arange(5.) In [25]: frame2 Out[25]: year state pop debt one 2000 Ohio 1.5 0.0 two 2001 Ohio 1.7 1.0 three 2002 Ohio 3.6 2.0 four 2001 Nevada 2.4 3.0 five 2002 Nevada 2.9 4.0 


將列表或數組賦值給某個列的時候,其長度必需要跟DataFrame的長度向匹配。若是賦值的是一個個Series ,就會精確的匹配DataFrame的索引,全部的空位都將被填上的缺失值。

In [26]: val=Series([-1.2,-1.5,-1.7],index=['two','four','five']) In [27]: frame2['debt']=val In [28]: frame2 Out[28]: year state pop debt one 2000 Ohio 1.5 NaN two 2001 Ohio 1.7 -1.2 three 2002 Ohio 3.6 NaN four 2001 Nevada 2.4 -1.5 five 2002 Nevada 2.9 -1.7 


爲不存在的列賦值會建立一個新列。關鍵字del用於刪除列:

In [29]: frame2['eastern']=frame2.state=='Ohio' In [30]: frame2 Out[30]: year state pop debt eastern one 2000 Ohio 1.5 NaN True two 2001 Ohio 1.7 -1.2 True three 2002 Ohio 3.6 NaN True four 2001 Nevada 2.4 -1.5 False five 2002 Nevada 2.9 -1.7 False In [31]: del frame2['eastern'] In [32]: frame2.columns Out[32]: Index([u'year', u'state', u'pop', u'debt'], dtype='object') 


另外一種常見的數據形式是嵌套字典(也就是字典的字典):

In [33]: pop={'Nevada':{2001:2.4,2002:2.9},'Ohio':{2000:1.5,2001:1.7, ...: 2002:3.6}} 


將它傳給DataFrame,就會被解釋爲:外層字典的鍵做爲列,內層鍵做爲行索引。

In [34]: frame3=DataFrame(pop) In [35]: frame3 Out[35]: Nevada Ohio 2000 NaN 1.5 2001 2.4 1.7 2002 2.9 3.6 


也能夠對結果進行轉置:

In [36]: frame3.T Out[36]: 2000 2001 2002 Nevada NaN 2.4 2.9 Ohio 1.5 1.7 3.6 


內層字典的鍵會被合併、排序以及造成最終的索引。若指定了顯式索引,則不會這樣:

In [37]: DataFrame(pop,index=[2001,2002,2003]) Out[37]: Nevada Ohio 2001 2.4 1.7 2002 2.9 3.6 2003 NaN NaN 


由Series組成的字典差很少也是同樣的用法:

In [40]: pdata={'Ohio':frame3['Ohio'][:-1],'Nevada':frame3['Nevada'][:2]} In [41]: DataFrame(pdata) Out[41]: Nevada Ohio 2000 NaN 1.5 2001 2.4 1.7 


若是設置了Data.Frame的index屬性和columns的name屬性,

In [42]: frame3.index.name='year';frame3.columns.name='state' In [43]: frame3 Out[43]: state Nevada Ohio year 2000 NaN 1.5 2001 2.4 1.7 2002 2.9 3.6 In [44]: frame3.values Out[44]: array([[ nan, 1.5], [ 2.4, 1.7], [ 2.9, 3.6]]) In [45]: frame3.values Out[45]: array([[ nan, 1.5], [ 2.4, 1.7], [ 2.9, 3.6]]) 


5.1.3索引對象
pandas的索引對象負責管理標籤和其餘元數據(好比軸名稱等)。構建Series或DataFrame時,所用到的任何數組或其餘序列的標籤都會被轉換成一個Index:

In [2]: import numpy as np In [3]: import pandas as pd In [5]: from pandas import Series,DataFrame In [6]: obj=Series(range(3),index=['a','b','c']) In [7]: index=obj.index In [8]: index Out[8]: Index([u'a', u'b', u'c'], dtype='object') In [9]: index[1:] Out[9]: Index([u'b', u'c'], dtype='object') 


Index對象是不可修改的,所以用戶不能對其修改:

In [10]: index[1]='d' --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-10-d3f90986bdb1> in <module>() ----> 1 index[1]='d' H:\Anaconda2-4.3.0.1\lib\site-packages\pandas\indexes\base.pyc in __setitem__(self, key, value) 1402 1403 def __setitem__(self, key, value): -> 1404 raise TypeError("Index does not support mutable operations") 1405 1406 def __getitem__(self, key): TypeError: Index does not support mutable operations 


不可修改性很是重要,由於這樣才能使得index對象在多個數據結構之間安全共享:

In [12]: index=pd.Index(np.arange(3)) In [13]: obj2=Series([1.5,-2.5,0],index=index) In [14]: obj2=Series([1.5,-2.5,0],index=index) In [16]: obj2.index is index Out[16]: True 



除了長得像數組,index的功能也相似一個固定大小的集合:

In [43]: frame3 Out[43]: state Nevada Ohio year 2000 NaN 1.5 2001 2.4 1.7 2002 2.9 3.6 In [46]: 'Ohio' in frame3.columns Out[46]: True In [47]: 2003 in frame3.index Out[47]: False 


5.2基本功能 
介紹操做Series和DataFrame中的數據的基本手段。

5.2.1從新索引
pandas對象的一個重要的方法就是reindex,做用是建立一個適應新索引的新對象。

In [33]: import pandas as pd from pandas import Series,DataFrame In [34]: obj=Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c']) In [35]: obj Out[35]: d 4.5 b 7.2 a -5.3 c 3.6 dtype: float64 


調用該Series的reindex將會根據新索引進行重排。若是某個索引值當前不存,就引入缺失值:

In [36]: obj2=obj.reindex(['a','b','c','d','e']) In [37]: obj2 Out[37]: a -5.3 b 7.2 c 3.6 d 4.5 e NaN dtype: float64 In [38]: obj.reindex(['a','b','c','d','e'],fill_value=0) Out[38]: a -5.3 b 7.2 c 3.6 d 4.5 e 0.0 dtype: float64 


對於時間序列這樣的有序數據,從新索引時可能須要作一些插值處理。method選項便可用達到此目的。例如:ffill能夠實現向前值填充:

In [39]: obj3=Series(['blue','purple','yellow'],index=[0,2,4]) In [40]: obj3.reindex(range(6),method='ffill') Out[40]: 0 blue 1 blue 2 purple 3 purple 4 yellow 5 yellow dtype: object 


下表中列出了可用的method選項。
參數 說明
fill或pad 前向填充(或搬運)值
bfill或backfill 後向填充(或搬運)值

對於DataFrame,reindex能夠修改(行)索引,列,或兩個都修改。若是僅傳入一個序列,則會從新索引行:

In [41]: frame=DataFrame(np.arange(9).reshape((3,3)),index=['a','c','d'],columns=['Ohio','Texas','California',]) In [52]: frame Out[53]: Ohio Texas California a 0 1 2 c 3 4 5 d 6 7 8 In [54]: frame2=frame.reindex(['a','b','c','d']) In [55]:frame2 Out[55]: 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 [56]: states=['Texas','Utah','California'] frame.reindex(columns=states) Out[57]: Texas Utah California a 1 NaN 2 c 4 NaN 5 d 7 NaN 8 


也能夠同時對行和列進行從新索引,而插值則只能按行應用(即軸0):

frame.reindex(index=['a','b','c','d'],method='ffill',columns=states) Out[58]: Texas Utah California a 1 NaN 2 b 1 NaN 2 c 4 NaN 5 d 7 NaN 8 


利用ix的標籤的=索引功能,從新索引任務能夠變得簡潔:

frame.ix[['a','b','c','d'],states] Out[59]: 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 



5.2.2丟棄指定軸上的項
丟棄某條軸上的一個或多個項,只要有一個索引數組或列表便可。
因爲須要執行一些數據整理和集合邏輯,因此drop方法返回的是一個在指定軸上刪除了指定值的新對象:

In [60]: obj=Series(np.arange(5.),index=['a','b','c','d','e']) In [61]: new_obj=obj.drop('c') In [62]: new_obj Out[62]: a 0.0 b 1.0 d 3.0 e 4.0 dtype: float64 In[63]: obj.drop(['d','c']) Out[63]: a 0.0 b 1.0 e 4.0 dtype: float64 


對於DataFrame,能夠刪除任意軸上的索引值:

In [66]: data=DataFrame(np.arange(16).reshape((4,4)),index=['Ohio','Colorado','Utah','New York'],columns=['one','two','three','four']) In[67]: data.drop(['Colorado','Ohio']) Out[67]: one two three four Utah 8 9 10 11 New York 12 13 14 15 In [68]: data.drop('two',axis=1) Out[68]: one three four Ohio 0 2 3 Colorado 4 6 7 Utah 8 10 11 New York 12 14 15 In [69]: data.drop(['two','four'],axis=1) Out[69]: one three Ohio 0 2 Colorado 4 6 Utah 8 10 New York 12 14 


5.2.3索引、選取和過濾
Series索引 (obj[...])的工做方式相似於NumPy數組的索引,只不過Series的索引值不僅是整數。例:

In [5]: obj=Series(np.arange(4.),index=['a','b','c','d']) In [6]: obj['b'] Out[6]: 1.0 In [7]: obj[1] Out[7]: 1.0 In [8]: obj[2:4] Out[8]: c 2.0 d 3.0 dtype: float64 In [10]: obj[['b','a','d']] Out[10]: b 1.0 a 0.0 d 3.0 dtype: float64 In [11]: obj[[1,3]] Out[11]: b 1.0 d 3.0 dtype: float64 In [12]: obj[obj<2] Out[12]: a 0.0 b 1.0 dtype: float64 


利用標籤的切片運算與普通的python切片運算不一樣,其末端是包含的(inclusive)

In [19]: obj['b':'c'] Out[19]: b 1.0 c 2.0 dtype: float64 


設置方式以下:

In [20]: obj['b':'c']=5 In [21]: obj Out[21]: a 0.0 b 5.0 c 5.0 d 3.0 dtype: float64 


如你所見,對DataFrame進行索引其實就是獲取一個或多個列:

In [24]: data=DataFrame(np.arange(16).reshape((4,4)),
index=['Ohio','Colorado','Utah','New York'],columns=['one','two','three','four'])

In [25]: data
Out[25]:
          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 [26]: data['two']
Out[26]:
Ohio         1
Colorado     5
Utah         9
New York    13
Name: two, dtype: int32

In [28]: data[['three','one']]
Out[28]:
          three  one
Ohio          2    0
Colorado      6    4
Utah         10    8
New York     14   12

In [30]: data[['three','one']]
Out[30]:
          three  one
Ohio          2    0
Colorado      6    4
Utah         10    8
New York     14   12


這種索引方式有幾個特殊狀況。首先經過切片或布爾數組進行選取行:

In [29]: data[:2] Out[29]: one two three four Ohio 0 1 2 3 Colorado 4 5 6 7 In [31]: data[data['three']>5] Out[31]: one two three four Colorado 4 5 6 7 Utah 8 9 10 11 New York 12 13 14 15 


另外一種用法使經過布爾型DataFrame進行索引:

In [32]: data<5 Out[32]: 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 [33]: data[data<5]=0 In [34]: data Out[34]: 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 


這段代碼使得DataFrame在語法上像ndarray
爲了在DataFrame的行上進行標籤索引,咱們引入專門的索引字段ix。使得你經過numpy式的標記法以及軸標籤的從DataFrame中選取行和列的子集。這是重現索引的簡單手段:

In [35]: data.ix['Colorado',['two','three']]
Out[35]:
two      5
three    6
Name: Colorado, dtype: int32

In [36]: data.ix[['Colorado','Utah'],[3,0,1]]
Out[36]:
          four  one  two
Colorado     7    0    5
Utah        11    8    9

In [37]: data.ix[2]
Out[37]:
one       8
two       9
three    10
four     11
Name: Utah, dtype: int32

In [38]: data.ix[:'Utah','two']
Out[38]:
Ohio        0
Colorado    5
Utah        9
Name: two, dtype: int32

In [39]: data.ix[data.three>5,:3]
Out[39]:
          one  two  three
Colorado    0    5      6
Utah        8    9     10
New York   12   13     14


5.2.4算術運算和數據對齊

In [5]: s1=Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e']) In [6]: s2=Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g']) In [7]: s1 Out[7]: a 7.3 c -2.5 d 3.4 e 1.5 dtype: float64 In [8]: s2 Out[8]: a -2.1 c 3.6 e -1.5 f 4.0 g 3.1 dtype: float64 


把他們相加:

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 [6]: df1=DataFrame(np.arange(9.).reshape((3,3)),columns=list('bcd'),index=['Ohio','Texas','Colorado']) In [7]: df2=DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon']) In [8]: df1 Out[8]: b c d Ohio 0.0 1.0 2.0 Texas 3.0 4.0 5.0 Colorado 6.0 7.0 8.0 In [9]: df2 Out[9]: b d e Utah 0.0 1.0 2.0 Ohio 3.0 4.0 5.0 Texas 6.0 7.0 8.0 Oregon 9.0 10.0 11.0 


將他們相加後,會返回一個新的DataFrame,其索引和列爲原來的那兩個DataFrame的並集:

In [10]: df1+df2 Out[10]: b c d e Colorado NaN NaN NaN NaN Ohio 3.0 NaN 6.0 NaN Oregon NaN NaN NaN NaN Texas 9.0 NaN 12.0 NaN Utah NaN NaN NaN NaN 


5.2.4.1在算術方法中填充值
在不一樣索引的對象進行算術運算時,你可能但願當一個對象中某個軸標籤在另外一個對象張找不到時填充一個特殊值:

In [20]: df1=DataFrame(np.arange(12.).reshape((3,4)),columns=list('abcd')) In [21]: df2=DataFrame(np.arange(20.).reshape((4,5)),columns=list('abcde')) In [22]: df1 Out[22]: a b c d 0 0.0 1.0 2.0 3.0 1 4.0 5.0 6.0 7.0 2 8.0 9.0 10.0 11.0 In [23]: df2 Out[23]: a b c d e 0 0.0 1.0 2.0 3.0 4.0 1 5.0 6.0 7.0 8.0 9.0 2 10.0 11.0 12.0 13.0 14.0 3 15.0 16.0 17.0 18.0 19.0 


將他們相加時,沒有重疊的位置就會產生NA值:

In [24]: df1+df2 Out[24]: 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 [26]: df1.add(df2,fill_value=0) Out[26]: 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 [28]: df1.reindex(columns=df2.columns,fill_value=0) Out[28]: a b c d e 0 0.0 1.0 2.0 3.0 0 1 4.0 5.0 6.0 7.0 0 2 8.0 9.0 10.0 11.0 0 


表5-7 靈活的算術方法
方法 說明
add 用於加法(+)的方法
sub 用於減法(-)的方法
div 用於乘法(*)的方法
mul 用於除法(/)的方法

5.2.4.2 DataFrame和Series之間的運算
跟NumPy數組同樣,DataFrame和Series的=之間的算術運算也是有明確規定的。
下面來計算一個二維數組與其某行之間的差:

In [29]: arr=np.arange(12.).reshape((3,4)) In [30]: arr Out[30]: array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]]) In [31]: arr[0] Out[31]: array([ 0., 1., 2., 3.]) In [32]: arr-arr[0] Out[32]: array([[ 0., 0., 0., 0.], [ 4., 4., 4., 4.], [ 8., 8., 8., 8.]]) 


上面的運算就叫作,廣播。
DataFrame和Series之間的運算差很少也是如此:

In [33]: frame=DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon']) In [34]: series=frame.ix[0] In [35]: frame Out[35]: b d e Utah 0.0 1.0 2.0 Ohio 3.0 4.0 5.0 Texas 6.0 7.0 8.0 Oregon 9.0 10.0 11.0 In [36]: series Out[36]: b 0.0 d 1.0 e 2.0 Name: Utah, dtype: float64 


默認狀況下,DataFrame和Series之間的算術運算符將Series的索引匹配到DataFrame的列,而後沿着行一直向下廣播:

In [37]: frame - series Out[37]: b d e Utah 0.0 0.0 0.0 Ohio 3.0 3.0 3.0 Texas 6.0 6.0 6.0 Oregon 9.0 9.0 9.0 


若是某個索引值在DataFrame的列或Series的索引中找不到,則參與運算的兩個對象就會被從新索引以造成並集:

In [38]: series2=Series(range(3),index=['b','e','f']) In [39]: frame+series2 Out[39]: b d e f Utah 0.0 NaN 3.0 NaN Ohio 3.0 NaN 6.0 NaN Texas 6.0 NaN 9.0 NaN Oregon 9.0 NaN 12.0 NaN 


若是你但願匹配行且在列上廣播,則必須使用算術運算方法:

In [40]: series3=frame['d'] In [41]: frame Out[41]: b d e Utah 0.0 1.0 2.0 Ohio 3.0 4.0 5.0 Texas 6.0 7.0 8.0 Oregon 9.0 10.0 11.0 In [42]: series3 Out[42]: Utah 1.0 Ohio 4.0 Texas 7.0 Oregon 10.0 Name: d, dtype: float64 In [43]: frame.sub(series3,axis=0) Out[43]: b d e Utah -1.0 0.0 1.0 Ohio -1.0 0.0 1.0 Texas -1.0 0.0 1.0 Oregon -1.0 0.0 1.0 


傳入的軸號就是但願匹配的軸。

5.2.5函數應用和映射
Numpy的ufuncs(元素級數組方法)也能夠用於操做pandas對象:

In [44]: frame=DataFrame(np.random.randn(4,3),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon']) In [45]: frame Out[45]: b d e Utah -0.172344 1.823441 -0.067380 Ohio -0.338604 -0.189082 -0.145676 Texas 1.310289 -0.518146 -0.231740 Oregon -1.880954 -0.400772 0.228320 In [46]: np.abs(frame) Out[46]: b d e Utah 0.172344 1.823441 0.067380 Ohio 0.338604 0.189082 0.145676 Texas 1.310289 0.518146 0.231740 Oregon 1.880954 0.400772 0.228320 


另外一個常見的操做,將函數應用到由各列或行所造成的一維數組上。DataFrame的apply方法便可實現此功能:

In [47]: f=lambda x:x.max() - x.min()

In [48]: frame.apply(f)
Out[48]:
b 3.191243
d 2.341587
e 0.460059
dtype: float64

In [49]: frame.apply(f,axis=1)
Out[49]:
Utah 1.995785
Ohio 0.192928
Texas 1.828435
Oregon 2.109274
dtype: float64


除標量外,傳遞給apply的函數還能夠返回由多個值組成的Series:

In [52]: def f(x): ...: return Series([x.min(),x.max()],index=['min','max']) ...: In [53]: frame.apply(f) Out[53]: b d e min -1.880954 -0.518146 -0.23174 max 1.310289 1.823441 0.22832 


此外,元素級的python函數也是能夠用的。
假如想獲得frame中各個浮點數的格式化字符串,使用applymap便可:

In [54]: format=lambda x:'%.2f' %x In [55]: frame.applymap(format) Out[55]: b d e Utah -0.17 1.82 -0.07 Ohio -0.34 -0.19 -0.15 Texas 1.31 -0.52 -0.23 Oregon -1.88 -0.40 0.23 


之因此叫作applymap,是由於Series有一個用於應用元素級函數的map的方法:

In [56]: frame['e'].map(format) Out[56]: Utah -0.07 Ohio -0.15 Texas -0.23 Oregon 0.23 Name: e, dtype: object 


5.2.6排序和排名
根據條件對數據集排序也是一種重要的內置運算。要對行或列索引進行排序(按字典順序),可使用sort_index方法,它將返回一個已經排序的新對象:

In [57]: obj=Series(range(4),index=['d','a','b','c']) In [58]: obj.sort_index() Out[58]: a 1 b 2 c 3 d 0 dtype: int64 


而對於DataFrame,則能夠根據任意一個軸上的索引進行排序:

In [59]: frame=DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=['d','a','b','c']) In [60]: frame.sort_index() Out[60]: d a b c one 4 5 6 7 three 0 1 2 3 In [61]: frame.sort_index(axis=1) Out[61]: a b c d three 1 2 3 0 one 5 6 7 4 


數據默認是按升序排列的,但也能夠降序排序:

In [64]: frame.sort_index(axis=1,ascending=False) Out[64]: d c b a three 0 3 2 1 one 4 7 6 5 


若要按值對Series進行排序,可使用order方法:

In [65]: obj=Series([4,7,-3,2]) In [66]: obj.order() Out[66]: 2 -3 3 2 0 4 1 7 dtype: int64 


在排序的時候,缺失值默認都會被放在了Series的末尾:

In [67]: obj=Series([4,np.nan,7,np.nan,-3,2]) In [68]: obj.order() Out[68]: 4 -3.0 5 2.0 0 4.0 2 7.0 1 NaN 3 NaN dtype: float64 


在DataFrame上,你可能但願根據一個或多個列中的值進行排序。將一個或多個列的名字傳遞給by選項便可達到該目的:

In [69]: frame=DataFrame({'b':[4,7,-3,2],'a':[0,1,0,1]}) In [70]: frame Out[70]: a b 0 0 4 1 1 7 2 0 -3 3 1 2 In [71]: frame.sort_index(by='b') Out[71]: a b 2 0 -3 3 1 2 0 0 4 1 1 7 


要根據多個列進行排序,傳入名稱的列表便可:

In [73]: frame.sort_index(by=['a','b']) Out[73]: a b 2 0 -3 0 0 4 3 1 2 1 1 7 


排名(ranking)跟排序關係密切,且會增設一個排名值(從1開始,一直到數組中有效數據的數量),跟numpy.argsort產生的間接排序索引差很少,只不過它能夠根據某種規則破壞平級關係。

下面介紹Series和DataFrame的rank方法。默認下:rank是經過「爲各組分配一個平均排名」的方式來破壞平級關係。

In [75]: obj=Series([7,-5,7,4,2,0,4]) In [76]: obj.rank() Out[76]: 0 6.5 1 1.0 2 6.5 3 4.5 4 3.0 5 2.0 6 4.5 dtype: float64 


也能夠根據值在原數據中出現的順序給出排名:

In [77]: obj.rank(method='first') Out[77]: 0 6.0 1 1.0 2 7.0 3 4.0 4 3.0 5 2.0 6 5.0 dtype: float64 


也能夠按降序進行排名:

In [78]: obj.rank(ascending=False,method='max') Out[78]: 0 2.0 1 7.0 2 2.0 3 4.0 4 5.0 5 6.0 6 4.0 dtype: float64 


表5-8 列出了全部用於破壞平級關係的method選項。DataFrame能夠在行或列上計算排名:

In [79]: frame=DataFrame({'b':[4.3,7,-3,2],'a':[0,1,0,1],'c':[-2,5,8,-2.5]}) In [80]: frame Out[80]: a b c 0 0 4.3 -2.0 1 1 7.0 5.0 2 0 -3.0 8.0 3 1 2.0 -2.5 In [81]: frame.rank(axis=1) Out[81]: a b c 0 2.0 3.0 1.0 1 1.0 3.0 2.0 2 2.0 1.0 3.0 3 2.0 3.0 1.0 


表5-8 :排名時用於破壞平級關係的method選項
method 說明
‘average’ 默認:在相等分組中,爲各個值分配平均排‘’
‘min’ 使用整個分組的最小排名
‘max’ 使用整個分組的最大排名
‘first’ 按值在原始數據中的出現順序分配排名

5.2.7帶有重複的軸索引
咱們看看下面這個簡單的帶有重複索引值的Series:

In [82]: obj=Series(range(5),index=['a','a','b','b','c']) In [83]: obj Out[83]: a 0 a 1 b 2 b 3 c 4 dtype: int64 


索引的is_unique屬性能夠告訴你他的值是不是惟一的:

In [84]: obj.index.is_unique Out[84]: False 


對於重複的索引,數據選取的行爲將會有些不一樣。若是某個索引對應的多個值,則返回一個Series,而對應單個值,則返回一個標量:

In [85]: obj['a'] Out[85]: a 0 a 1 dtype: int64 In [86]: obj['c'] Out[86]: 4 


對DataFrame的行進行索引時候也是如此:

In [87]: df=DataFrame(np.random.randn(4,3),index=['a','a','b','b']) In [88]: df Out[88]: 0 1 2 a 0.056598 1.592208 -0.576368 a 0.842511 -0.085418 0.818032 b 1.347421 -0.239196 -0.543597 b -0.598395 0.966395 0.285722 In [89]: df.ix['b'] Out[89]: 0 1 2 b 1.347421 -0.239196 -0.543597 b -0.598395 0.966395 0.285722 


5.3彙總和計算描述性統計
pandas對象擁有一組經常使用的數學和統計方法。他們大部分都屬於約簡和彙總統計,用於從Series中提取單個值(如mean或sum)或從DataFrame的行或列中提取一個Series。跟對應的NumPy數組方法相比,他們都是基於沒有缺失數據的假設而構建的。

下面是一個簡單的DataFrame:

In [90]: df=DataFrame([[1.4,np.nan],[7.1,-4.5],[np.nan,np.nan],[0.75,-1.3]],index=['a','b','c','d'],columns=['one','two']) In [91]: df Out[91]: one two a 1.40 NaN b 7.10 -4.5 c NaN NaN d 0.75 -1.3 


調用DataFrame的sum方法將會返回一個含有列的小計的Series:

In [92]: df.sum() Out[92]: one 9.25 two -5.80 dtype: float64 


傳入axis=1 將會按行進行求和計算:

In [93]: df.sum(axis=1) Out[93]: a 1.40 b 2.60 c 0.00 d -0.55 dtype: float64 


NA值將會被自動剔除,除非整個切片都是NA。經過skipna選項能夠禁用該功能:

In [94]: df.mean(axis=1,skipna=False) Out[94]: a NaN b 1.300 c NaN d -0.275 dtype: float64 


表5-9給出了約簡方法經常使用選項

有些方法(如idxmin和idxmax)返回的是間接統計(好比達到最大值或最小值的索引):

In [95]: df.idxmax() Out[95]: one b two d dtype: object 


一些方法則是累計型的:

In [96]: df.cumsum() Out[96]: one two a 1.40 NaN b 8.50 -4.5 c NaN NaN d 9.25 -5.8 


還有一些方法,既不是約簡型也不是累計型。

In [97]: df.describe() Out[97]: one two count 3.000000 2.000000 mean 3.083333 -2.900000 std 3.493685 2.262742 min 0.750000 -4.500000 25% 1.075000 -3.700000 50% 1.400000 -2.900000 75% 4.250000 -2.100000 max 7.100000 -1.300000 


對於非數值型的數據,describe會產生另外一種彙總統計:

In [98]: obj=Series(['a','a','b','c']*4) In [99]: obj.describe() Out[99]: count 16 unique 3 top a freq 8 dtype: object 


表5-10列出了全部與描述統計相關的方法。

5.3.1相關係數和協方差

有些彙總統計(如先關係數和協方差)是經過參數計算出來的。

5.3.2惟一值、值計數以及成員資格
從一維Series的值中抽取信息。如下這個Series爲例:

In [107]: obj=Series(['c','a','d','a','a','b','b','c','c']) 


第一個函數是unique,能夠獲得Sseries中的惟一數組:

In [108]: uniques=obj.unique() In [109]: uniques Out[109]: array(['c', 'a', 'd', 'b'], dtype=object) 


返回值的惟一未排序的,若是須要的話,能夠對結果再次進行排序(unique.sort())
value_counts 用於計算一個Series中各值出現的頻率:

In [110]: obj.value_counts() Out[110]: c 3 a 3 b 2 d 1 dtype: int64 


爲了方便查看,結果Series是按值頻率降序排列的。
value_counts 仍是一個頂級的pandas方法,可用於任何數組的或序列:

In [111]: pd.value_counts(obj.values,sort=False) Out[111]: a 3 c 3 b 2 d 1 dtype: int64 


最後isin,它用於判斷矢量化最集合的成員資格,可用於選取Series中或DataFrame列中的數據的子集:

In [112]: mask=obj.isin(['b','c']) In [113]: mask Out[113]: 0 True 1 False 2 False 3 False 4 False 5 True 6 True 7 True 8 True dtype: bool In [114]: obj[mask] Out[114]: 0 c 5 b 6 b 7 c 8 c dtype: object 


有時,你可能須要獲得DataFrame中多個相關的一張柱狀圖。

In [115]: data=DataFrame({'Qu1':[1,3,4,3,4],'Qu2':[2,3,1,2,3],'Qu3':[1,5,2,4,4]}) In [116]: data Out[116]: Qu1 Qu2 Qu3 0 1 2 1 1 3 3 5 2 4 1 2 3 3 2 4 4 4 3 4 In [117]: result=data.apply(pd.value_counts).fillna(0) In [118]: result Out[118]: Qu1 Qu2 Qu3 1 1.0 1.0 1.0 2 0.0 2.0 1.0 3 2.0 2.0 0.0 4 2.0 0.0 2.0 5 0.0 0.0 1.0 


5.4處理缺失數據
處理缺失數據(missing data)在大部分的數據分析應用中很常見。pandas的設計目標之一就是讓缺失數據的處理任務儘可能輕鬆。

pandas使用浮點數NaN(Not a Number)表示浮點和非浮點數組中的缺失數據。只是一個便於檢測出來的標記而已:

In [119]: string_data=Series(['aardvark','arrichoke',np.nan,'avocado']) In [120]: string_data Out[120]: 0 aardvark 1 arrichoke 2 NaN 3 avocado dtype: object In [121]: string_data.isnull() Out[121]: 0 False 1 False 2 True 3 False dtype: bool 



python內置的None值也會被當作NA處理:

In [123]: string_data.isnull() Out[123]: 0 True 1 False 2 True 3 False dtype: bool 


5.4.1濾除缺失數據
對於一個Series,dropna返回一個僅含有非空數據的和索引值的Series:

In [124]: from numpy import nan as NA In [125]: data=Series([1,NA,3.5,NA,7]) In [126]: data.dropna() Out[126]: 0 1.0 2 3.5 4 7.0 dtype: float64 


還能夠經過布爾型索引達到這個目的:

In [127]: data[data.notnull()] Out[127]: 0 1.0 2 3.5 4 7.0 dtype: float64 


對於DataFrame對象,若是但願丟棄全NA或NA的行貨列,dropna默認丟棄任何含有缺失值的行:

In [129]: data=DataFrame([[1.,6.5,3.],[1.,NA,NA],[NA,NA,NA],[NA,6.5,3.]]) In [130]: cleaned=data.dropna() In [131]: data Out[131]: 0 1 2 0 1.0 6.5 3.0 1 1.0 NaN NaN 2 NaN NaN NaN 3 NaN 6.5 3.0 In [132]: cleaned Out[132]: 0 1 2 0 1.0 6.5 3.0 


傳入how=‘all’ 將只丟棄全爲NA的那些行:

In [133]: data.dropna(how='all') Out[133]: 0 1 2 0 1.0 6.5 3.0 1 1.0 NaN NaN 3 NaN 6.5 3.0 


要用這種方式丟棄列,只需傳入axis=1便可:

In [134]: data[4]=NA In [135]: data Out[135]: 0 1 2 4 0 1.0 6.5 3.0 NaN 1 1.0 NaN NaN NaN 2 NaN NaN NaN NaN 3 NaN 6.5 3.0 NaN In [136]: data.dropna(axis=1,how='all') Out[136]: 0 1 2 0 1.0 6.5 3.0 1 1.0 NaN NaN 2 NaN NaN NaN 3 NaN 6.5 3.0 


另外一個濾出DataFrame行的問題涉及時間序列數據。
假設你只想留下一部分觀測數據,能夠用thresh參數實現此目的:

In [137]: df=DataFrame(np.random.randn(7,3)) In [138]: df.ix[:4,1]=NA;df.ix[:2,2]=NA In [139]: df Out[139]: 0 1 2 0 0.452896 NaN NaN 1 1.071009 NaN NaN 2 -0.135804 NaN NaN 3 0.010116 NaN 0.064880 4 -1.038639 NaN -0.756553 5 0.738134 -1.505505 -0.052306 6 -1.712077 0.386785 0.436945 In [140]: df.dropna(thresh=3) Out[140]: 0 1 2 5 0.738134 -1.505505 -0.052306 6 -1.712077 0.386785 0.436945 


5.4.2填充缺失數據
若是不想濾除數據,而是但願填充數據。
經過一個常數來fillna就會將缺失值替換爲那個常數值:

In [141]: df.fillna(0) Out[141]: 0 1 2 0 0.452896 0.000000 0.000000 1 1.071009 0.000000 0.000000 2 -0.135804 0.000000 0.000000 3 0.010116 0.000000 0.064880 4 -1.038639 0.000000 -0.756553 5 0.738134 -1.505505 -0.052306 6 -1.712077 0.386785 0.436945 


經過一個字典調用fillna,就能夠實現對不一樣的列填充不一樣的值:

In [142]: df.fillna({1:0.5,3:-1}) Out[142]: 0 1 2 0 0.452896 0.500000 NaN 1 1.071009 0.500000 NaN 2 -0.135804 0.500000 NaN 3 0.010116 0.500000 0.064880 4 -1.038639 0.500000 -0.756553 5 0.738134 -1.505505 -0.052306 6 -1.712077 0.386785 0.436945 


fillna默認會返回新對象,可是也能夠對現有的對象進行修改:

In [143]: _=df.fillna(0,inplace=True) In [144]: df Out[144]: 0 1 2 0 0.452896 0.000000 0.000000 1 1.071009 0.000000 0.000000 2 -0.135804 0.000000 0.000000 3 0.010116 0.000000 0.064880 4 -1.038639 0.000000 -0.756553 5 0.738134 -1.505505 -0.052306 6 -1.712077 0.386785 0.436945 


對reindex有效的那些插值方法也能夠用於fillna:

In [145]: df=DataFrame(np.random.randn(6,3)) In [146]: df.ix[2:,1]=NA;df.ix[4:,2]=NA In [147]: df Out[147]: 0 1 2 0 0.501394 -1.735750 0.197643 1 2.099104 1.441581 0.743717 2 -0.451567 NaN -0.150315 3 -0.032894 NaN 0.418310 4 1.285966 NaN NaN 5 -0.058611 NaN NaN In [148]: df.fillna(method='ffill') Out[148]: 0 1 2 0 0.501394 -1.735750 0.197643 1 2.099104 1.441581 0.743717 2 -0.451567 1.441581 -0.150315 3 -0.032894 1.441581 0.418310 4 1.285966 1.441581 0.418310 5 -0.058611 1.441581 0.418310 In [149]: df.fillna(method='ffill',limit=2) Out[149]: 0 1 2 0 0.501394 -1.735750 0.197643 1 2.099104 1.441581 0.743717 2 -0.451567 1.441581 -0.150315 3 -0.032894 1.441581 0.418310 4 1.285966 NaN 0.418310 5 -0.058611 NaN 0.418310 


只要稍微動腦子,就能夠利用fillna的=實現許多的別的功能。
好比,傳入Series的平均值或中位數:

In [150]: data=Series([1.,NA,3.5,NA,7]) In [151]: data.fillna(data.mean()) Out[151]: 0 1.000000 1 3.833333 2 3.500000 3 3.833333 4 7.000000 dtype: float64 


5.5層次化索引
層次化索引,是你能在一個軸上擁有多個(兩個以上)索引級別。
即能以低緯度形式處理高緯度數據。

咱們來建立一個Series,並用一個由列表或數組組成的列表做爲索引:

In [152]: 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]]) In [153]: data Out[153]: a 1 0.024162 2 0.969526 3 -0.215712 b 1 1.136933 2 -0.158487 3 0.482377 c 1 -0.551888 2 -1.090750 d 2 -0.073204 3 -1.217613 dtype: float64 



這就是帶有MultiIndex 索引的Series 的格式輸出格式。索引之間的「間隔」表示「直接使用上面的標籤」:

In [154]: data.index Out[154]: MultiIndex(levels=[[u'a', u'b', u'c', u'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]]) 


對於一個層次化索引的對象,選取數據子集的操做很簡單:

data['b'] Out[155]: 1 1.136933 2 -0.158487 3 0.482377 dtype: float64 data['b':'c'] Out[156]: b 1 1.136933 2 -0.158487 3 0.482377 c 1 -0.551888 2 -1.090750 dtype: float64 data.ix[['b','d']] Out[158]: b 1 1.136933 2 -0.158487 3 0.482377 d 2 -0.073204 3 -1.217613 dtype: float64 


甚至還能夠在「內層」中進行選取:

In [159]: data[:,2] Out[159]: a 0.969526 b -0.158487 c -1.090750 d -0.073204 dtype: float64 


層次化索引的在數據重塑和基於分組的操做(如透視表生成)中扮演重要角色。好比說,這段數據能夠經過unstack方法被從新安排到一個DataFrame中:

n [160]: data.unstack() Out[160]: 1 2 3 a 0.024162 0.969526 -0.215712 b 1.136933 -0.158487 0.482377 c -0.551888 -1.090750 NaN d NaN -0.073204 -1.21761 


unstack的逆運算是stack:

In [161]: data.unstack().stack() Out[161]: a 1 0.024162 2 0.969526 3 -0.215712 b 1 1.136933 2 -0.158487 3 0.482377 c 1 -0.551888 2 -1.090750 d 2 -0.073204 3 -1.217613 dtype: float64 


對於一個DataFrame,每條軸均可以分層索引:

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


各層均可以有名字(能夠是字符串,也能夠是python對象)。若是指定了名稱,他們就會顯示在控制檯輸出中:

In [164]: frame.index.names=['key1','key2'] In [165]: frame.columns.names=['state','color'] In [166]: frame Out[166]: 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 


有了分部的列索引,所以能夠選取列分組:

In [167]: frame['Ohio'] Out[167]: color Green Red key1 key2 a 1 0 1 2 3 4 b 1 6 7 2 9 10 


能夠單獨的建立MultiIndex 而後複用,上面那個DataFrame中的(分級)列能夠這樣建立:

In [168]: MultiIndex.from_arrays([['Ohio','Ohio','Colorado'],['Green','Red','Green']],names=['state','color']) 


5.5.1重排分級順序
若是須要調整某條軸上各級別的順序,或根據指定界級別上的值對數據進行排序。swaplevel接受兩個級別編號或名稱,並返回一個互換級別的新對象(但數據不會發生變化):

In [169]: frame.swaplevel('key1','key2') Out[169]: 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 


而sortleval則根據單個級別中的值對數據進行排序(穩定的)。交流級別時,經常也會用到sortlevel,這樣最終的結果就是有序的了:

In [170]: frame.sortlevel(1) Out[170]: state Ohio Colorado color Green Red Green key1 key2 a 1 0 1 2 b 1 6 7 8 a 2 3 4 5 b 2 9 10 11 In [172]: frame.swaplevel(0,1).sortlevel(0) Out[172]: 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 


5.5.2根據級別彙總統計
許多對DataFrame 和Series的描述和彙總統計都有一個leve選項,用於指定在某條軸上對求和的級別,再也上面的那個DataFrame爲例子,咱們根據行或列上的級別進行求和:

In [173]: frame.sum(level='color',axis=1) Out[173]: color Green Red key1 key2 a 1 2 1 2 8 4 b 1 14 7 2 20 10 In [174]: frame.sum(level='key2') Out[174]: state Ohio Colorado color Green Red Green key2 1 6 8 10 2 12 14 16 

5.5.3使用DataFrame的列
將DataFrame的一個或多個列當作行索引來用,或者可能但願將行索引變成DataFrame要的列。

In [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]}) In [15]: frame Out[15]: 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:

In [17]: frame2 Out[17]: 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中移除,可是也能夠將其保留:

In [18]: frame.set_index(['c','d'],drop=False) Out[18]: 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恰好相反,層次化索引的級別會被轉移到列裏面:

In [20]: frame2.reset_index() Out[20]: 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 


5.6其餘有關pandas的話題
5.6.1整數索引
操做由整數索引的pandas對象經常會讓新手抓狂,由於他們跟內置的python數據結構(如列表和元組)在索引語義上有些不一樣。
例如,你可能認爲下面的代碼不會報錯。

In [24]: ser=Series(np.arange(3.)) In [25]: ser[-1] --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-25-3cbe0b873a9e> in <module>() ----> 1 ser[-1] pandas\src\hashtable_class_helper.pxi in pandas.hashtable.Int64HashTable.get_item (pandas\hashtable.c:85 08)() KeyError: -1L 


雖然pandas會「求助於」整數索引,可是沒有哪一種方法可以既不引入bug,又能解決問題的。
咱們有一個含有0,1,2的索引,可是很難推斷出用戶想要什麼:

In [26]: ser Out[26]: 0 0.0 1 1.0 2 2.0 dtype: float64 


相反,對於一個非整數索引,就沒有這樣的歧義:

In [30]: ser2=Series(np.arange(3.),index=['a','b','c']) In [31]: ser2[-1] Out[31]: 2.0 


爲了保持良好的一致性,若是你的軸索引含有索引器,那麼根據整數進行數據選取的操做蔣老是面向標籤的。這也包括用ix進行切片:

In [32]: ser.ix[:1] Out[32]: 0 0.0 1 1.0 dtype: float64 


若是須要可靠的,不考慮索引類型的,基於位置的索引,可使用Series 的 iget_value 方法和DataFrame的irow和icol方法:

In [33]: ser3=Series(range(3),index=[-5,1,3]) In [35]: ser3.iget_value(2) Out[35]: 2 In [37]: frame=DataFrame(np.arange(6).reshape(3,2),index=[2,0,1]) In [38]: frame.irow(0) Out[38]: 0 0 1 1 Name: 2, dtype: int32 



聲明:

以上學習筆記來自

《利用python進行數據分析》Wes McKinney 編著 唐學韜等譯 機械工業出版社

相關文章
相關標籤/搜索