1. 程式人生 > >python科學計算四:pandas

python科學計算四:pandas

Pandas是python的一個數據分析包,最初由AQR Capital Management於2008年4月開發,並於2009年底開源出來,目前由專注於Python資料包開發的PyData開發team繼續開發和維護,屬於PyData專案的一部分。Pandas最初被作為金融資料分析工具而開發出來,因此,pandas為時間序列分析提供了很好的支援。 Pandas的名稱來自於面板資料(panel data)和python資料分析(data analysis)。panel data是經濟學中關於多維資料集的一個術語,在Pandas中也提供了panel的資料型別。 這篇文章會介紹一些Pandas的基本知識,偷了些懶其中採用的例子大部分會來自官方的

10分鐘學Pandas。我會加上個人的理解,幫助大家記憶和學習。

Pandas中的資料結構

Series:一維陣列,與Numpy中的一維array類似。二者與Python基本的資料結構List也很相近,其區別是:List中的元素可以是不同的資料型別,而Array和Series中則只允許儲存相同的資料型別,這樣可以更有效的使用記憶體,提高運算效率。

Time- Series:以時間為索引的Series。

DataFrame:二維的表格型資料結構。很多功能與R中的data.frame類似。可以將DataFrame理解為Series的容器。以下的內容主要以DataFrame為主。

Panel :三維的陣列,可以理解為DataFrame的容器。

建立DataFrame

首先引入Pandas及Numpy:

Python
1 2 importpandas aspd importnumpy asnp

官方推薦的縮寫形式為pd,你可以選擇其他任意的名稱。 DataFrame是二維的資料結構,其本質是Series的容器,因此,DataFrame可以包含一個索引以及與這些索引聯合在一起的Series,由於一個Series中的資料型別是相同的,而不同Series的資料結構可以不同。因此對於DataFrame來說,每一列的資料結構都是相同的,而不同的列之間則可以是不同的資料結構。或者以資料庫進行類比,DataFrame中的每一行是一個記錄,名稱為Index的一個元素,而每一列則為一個欄位,是這個記錄的一個屬性。 建立DataFrame有多種方式:

1、以字典的字典或Series的字典的結構構建DataFrame,這時候的最外面字典對應的是DataFrame的列,內嵌的字典及Series則是其中每個值。

Python 使用 CTRL+C 複製,使用 CTRL+V 貼上。
1 2 d={one:Series([1.,2.,3.],index=[a,b,c]),two:Series([1.,2.,3.,4.],index=[a,b,c,d])} df=pd.DataFrame(d)

輸出:

pandas_101_01

pandas_101_01

可以看到d是一個字典,其中one的值為Series有3個值,而two為Series有4個值。由d構建的為一個4行2列的DataFrame。其中one只有3個值,因此d行one列為NaN(Not a Number)–Pandas預設的缺失值標記。

2、從列表的字典構建DataFrame,其中巢狀的每個列表(List)代表的是一個列,字典的名字則是列標籤。這裡要注意的是每個列表中的元素數量應該相同。否則會報錯:

Python
1 ValueError:arrays must allbe same length

3、從字典的列表構建DataFrame,其中每個字典代表的是每條記錄(DataFrame中的一行),字典中每個值對應的是這條記錄的相關屬性。

Python
1 2 3 d=[{'one':1,'two':1},{'one':2,'two':2},{'one':3,'two':3},{'two':4}] df=pd.DataFrame(d,index=['a','b','c','d'],columns=['one','two']) df.index.name='index'

以上的語句與以Series的字典形式建立的DataFrame相同,只是思路略有不同,一個是以列為單位構建,將所有記錄的不同屬性轉化為多個Series,行標籤冗餘,另一個是以行為單位構建,將每條記錄轉化為一個字典,列標籤冗餘。使用這種方式,如果不通過columns指定列的順序,那麼列的順序會是隨機的。

個人經驗是對於從一些已經結構化的資料轉化為DataFrame似乎前者更方便,而對於一些需要自己結構化的資料(比如解析Log檔案,特別是針對較大資料量時),似乎後者更方便。建立了DataFrame後可以通過index.name屬性為DataFrame的索引指定名稱。

檢視資料

head和tail方法可以顯示DataFrame前N條和後N條記錄,N為對應的引數,預設值為5。這通常是拿到DataFrame後的第一個命令,可以方便的瞭解資料內容和含義。

Pandas_101_02

Pandas_101_02

index(行)和columns(列)屬性,可以獲得DataFrame的行和列的標籤。這也是瞭解資料內容和含義的重要步驟。

Pandas_101_03

Pandas_101_03

decribe方法可以計算各個列的基本描述統計值。包含計數,平均數,標準差,最大值,最小值及4分位差。

Pandas_101_04

Pandas_101_04

行列轉置

Pandas_101_05

Pandas_101_05

DataFrame提供了多種排序方式。

Python
1 df.sort_index(axis=1,ascending=False)

sort_index可以以軸的標籤進行排序。axis是指用於排序的軸,可選的值有0和1,預設為0即行標籤(Y軸),1為按照列標籤排序。 ascending是排序方式,預設為True即降序排列。

Python
1 2 df.sort(columns='two') df.sort(columns=['one','two'],ascending=[0,1])

DataFrame也提供按照指定列進行排序,可以僅指定一個列作為排序標準(以單獨列名作為columns的引數),也可以進行多重排序(columns的引數為一個列名的List,列名的出現順序決定排序中的優先順序),在多重排序中ascending引數也為一個List,分別與columns中的List元素對應。

讀寫資料

DataFrame可以方便的讀寫資料檔案,最常見的檔案為CSV或Excel。Pandas讀寫Excel檔案需要openpyxl(Excel 2007), xlrd/xlwt(Excel 2003)。

從CSV中讀取資料:

Python
1 df=pd.read_csv('foo.csv')

將DataFrame寫入CSV:

Python
1 df.to_csv('foo.csv')

從Excel中讀取資料:

Python
1 2 xls=ExcelFile('foo.xlsx') xls.parse('sheet1',index_col=None,na_values=['NA'])

先定義一個Excel檔案,用xls.parse解析sheet1的內容,index_col用於指定index列,na_values定義缺失值的標識。

將DataFrame寫入Excel檔案:

Python
1 df.to_excel('foo.xlsx',sheet_name='sheet1')

預設的sheet為sheet1,也可以指定其他sheet名。

資料切片

通過下標選取資料:

Python
1 2 df['one'] df.one

以上兩個語句是等效的,都是返回df名稱為one列的資料,返回的為一個Series。

Python
1 2 df[0:3] df[0]

下標索引選取的是DataFrame的記錄,與List相同DataFrame的下標也是從0開始,區間索引的話,為一個左閉右開的區間,即[0:3]選取的為1-3三條記錄。與此等價,還可以用起始的索引名稱和結束索引名稱選取資料:

Python
1 df['a':'b']

有一點需要注意的是使用起始索引名稱和結束索引名稱時,也會包含結束索引的資料。以上兩種方式返回的都是DataFrame。

使用標籤選取資料:

Python
1 2 3 df.loc[行標籤,列標籤] df.loc['a':'b']#選取ab兩行資料 df.loc[:,'one']#選取one列的資料

df.loc的第一個引數是行標籤,第二個引數為列標籤(可選引數,預設為所有列標籤),兩個引數既可以是列表也可以是單個字元,如果兩個引數都為列表則返回的是DataFrame,否則,則為Series。

使用位置選取資料:

Python
1 2 3 4 5 6 df.iloc[行位置,列位置] df.iloc[1,1]#選取第二行,第二列的值,返回的為單個值 df.iloc[0,2],:]#選取第一行及第三行的資料 df.iloc[0:2,:]#選取第一行到第三行(不包含)的資料 df.iloc[:,1]#選取所有記錄的第一列的值,返回的為一個Series df.iloc[1,:]#選取第一行資料,返回的為一個Series

PS:loc為location的縮寫,iloc則為integer & location的縮寫

通過邏輯指標進行資料切片:

Python
1 2 3 df[邏輯條件] df[df.one>=2]#單個邏輯條件 df[(df.one>=1)&(df.one<3)]#多個邏輯條件組合

這種方式獲得的資料切片都是DataFrame。

基本運算

Pandas支援基本的運算及向量化運算。

Python
1 2 3 df.mean()#計算列的平均值,引數為軸,可選值為0或1.預設為0,即按照列運算 df.sum(1)#計算行的和 df.apply(lambdax:x.max()-x.min())#將一個函式應用到DataFrame的每一列,這裡使用的是匿名lambda函式,與R中apply函式類似

DataFrame的合併

Contact:

Python
1 2 3 4 ds=[{'one':4,'two':2},{'one':5,'two':3},{'one':6,'two':4},{'two':7,'three':10}] dfs=pd.DataFrame(ds,index=['e','f','g','h']) ##構建一個新的DataFrame,dfs df_t=pd.concat([df,dfs])#合併兩個DataFrame

Merge(類似SQL中的Join操作):

Python
1 2 3 4 left=pd.DataFrame({'key':['foo1','foo2'],'lval':[1,2]}) right=pd.DataFrame({'key':['foo1','foo2'],'rval':[4,5]}) #構建了兩個DataFrame pd.merge(left,right,on='key')#按照key列將兩個DataFrame join在一起

DataFrame中的Group by:

Python
1 2 3 df=pd.DataFrame({'A':['foo','bar','foo','bar','foo','bar','foo','foo'],'B':['one','one','two','three','two','two','one','three'],'C':randn(8),'D':randn(8)})&nbsp; df.groupby('A').sum()#按照A列的值分組求和 df.groupby(['A','B']).sum()##按照A、B兩列的值分組求和

構建透視表

Python
1 2 df=pd.DataFrame({'A':['one','one','two','three']*3,'B':['A','B','C']*4,'C':['foo','foo','foo','bar','bar','bar']*2,'D':np.random.randn(12),'E':np.random.randn(12)}) pd.pivot_table(df,values='D',rows=[