官术网_书友最值得收藏!

2.2 Pandas:表格處理

Pandas提供了3種數據類型,分別是Series、DataFrame和Panel。其中,Series用于保存一維數據,DataFrame用于保存二維數據,Panel用于保存三維或者可變維數據,其提供的數據結構使得Python做數據處理變得非常快速與簡單。平常的數據分析最常用的數據類型為Series和DataFrame,而Panel較少用到。在Python中調用Pandas往往使用如下約定俗成的方式:

2.2.1 Series數據結構

Series本質上是一個含有索引的一維數組,看起來,其包含一個左側可以自動生成(也可以手動指定)的index和右側的values值,分別使用s.index s.values進行查看。index返回一個index對象,而values則返回一個array(見表2-2-1)。

Series就是一個帶有索引的列表,為什么我們不使用字典呢?一個優勢是,Series更快,其內部是向量化運行的,和迭代相比,使用Series可以獲得顯著的性能上的優勢。

表2-2-1 Series的創建與屬性

2.2.2 數據結構:DataFrame

DataFrame(數據框)類似于Excel電子表格,也與R語言中DataFrame的數據結構類似。創建類DataFrame實例對象的方式有很多,包括如下幾種(見表2-2-2)。

● 使用list或者ndarray對象創建DataFrame:

● 使用字典創建DataFrame:使用字典創建DataFrame實例時,利用DataFrame可以將字典的鍵直接設置為列索引,并且指定一個列表作為字典的值,字典的值便成為該列索引下所有的元素。

需要注意的是:數據框的行索引默認是從0開始的。

表2-2-2 數據框數據的選取

● 獲取數據框的行數、列數和維數:df.shape[0]或len(df)、df.shape[1]、df.shape。

● 獲取數據框的列名或行名:df.columns、df.index。

■ 重新定義列名:df.columns=["X","Y","Z"]。

■ 重新更改某列的列名:df.rename(columns={'x':'X'},inplace=True)。注意,如果缺少inplace選項,則不會更改,而是增加新列。

● 觀察數據框的內容。

■df.info():info屬性表示打印DataFrame的屬性信息。

■df.head():查看DataFrame前五行的數據信息。

■df.tail():查看DataFrame最后五行的數據信息。

數據框的多重索引:通常DataFrame(數據框)只有一列索引,但是有時候要用到多重索引。表2-2-3中的df.set_index(['X','year'])就有兩層索引,第0級索引為“X”,第1級索引為“year”,這時使用loc方法選擇數據。

表2-2-3 數據框的多重索引

空數據框的創建:空數據框的創建在需要自己構造繪圖的數據框數據信息時,尤為重要。有時候,在繪制復雜的數據圖表時,我們需要對現有的數據進行插值、擬合等處理時,再使用空的數據框存儲新的數據,最后使用新的數據框繪制圖表。創建空數據框的方法很簡單:

網格分布型數據的創建:在三維插值展示時尤為重要。結合np.meshgrid()函數可以創建網格分布型數據框,如下所示。np.meshgrid()函數就是用兩個坐標軸上的點在平面上畫網格(當傳入的參數是兩個的時候)。也可以指定多個參數,比如3個參數,那么就可以用三個一維的坐標軸上的點在三維平面上畫網格(見表2-2-4)。

表2-2-4 網格分布型數據的創建

2.2.3 數據類型:Categorical

Pandas擁有特殊的數據結構類型:Categorical(分類)可以用于承載基于整數的類別展示或編碼的數據,可分為類別型和有序型,類似于R語言里面的因子向量(factor)。分類數據類型可以看成是包含了額外信息的列表,這額外的信息就是不同的類別,可以稱之為類別(categories)。分類數據類型在Python的plotnine包中很重要,因為它決定了數據的分析方式以及如何進行視覺呈現。

1.分類數據的創建

一個分類數據不僅包括分類變量本身,還可能包括變量不同的類別(即使它們在數據中不出現)。分類函數pd.Categorical()用下面的選項創建一個分類數據。對于字符型列表,分類數據的類別默認依字母順序創建:[Fair,Good,Ideal,Premium,Very Good]。

很多時候,按默認的字母順序排序的因子很少能夠讓人滿意。因此,可以指定類別選項來覆蓋默認排序。更改分類數據的類別為[Good,Fair,Very Good,Ideal,Premium],可以在使用pd.Categorical()函數創建分類數據的時候就直接設定好類別。

2.類別的更改

對于已經創建的分類數據或者數據框,可以使用*.astype()函數指定類別選項來覆蓋默認排序,從而將分類數據的類別更改為[Good,Fair,Very Good,Ideal,Premium]。

當ordered=True時,類別為有序的[Good<Fair<Very Good<Ideal<Premium]。

3.類型的轉換

有時,我們需要獲得分類數據的類別(categories)和編碼(codes),如表2-2-5所示。這樣相當于將分類型數據轉換成數值型數據。

表2-2-5 因子類型的轉換

如果需要從另一個數據源獲得分類編碼數據,則可以使用from_codes()函數構造。如下所示的Cut_Factor3輸出結果為[Fair,Good,Ideal,Fair,Fair,Good],其中categories(3,object)為:[Fair,Good,Ideal]。

2.2.4 表格的變換

使用Python的plotnine包繪圖或者做分組groupby()計算處理時,通常是使用一維數據列表的數據框。但是如果導入的數據表格是二維數據列表,那我們需要使用pd.melt()函數,可以將二維數據列表的數據框轉換成一維數據列表。我們首先構造數據框df:

(1)將寬數據轉換為長數據。將多行聚集成列,從而二維表變成一維表(見圖2-2-1):

圖2-2-1 表格變換處理的示意案例

其中,id.vars("x")表示由標識變量構成的向量,用于標識觀測的變量;variable.name("year")表示用于保存原始變量名的變量的名稱;value.name("value")表示用于保存原始值的名稱。

(2)將長數據轉換為寬數據。將一列根據變量展開為多行,從而一維表變二維表:

2.2.5 變量的變換

有時候,我們需要對數據框某列的每個元素都進行運算處理,從而產生并添加新的列。我們可以直接對數據框的某列進行加減乘除某個數值的運算,從而產生新列:

使用Python的transform()函數,結合lamdba表達式可以為原數據框添加新的列,改變原變量列的值。同時結合條件語句的三元表達式ifelse()進行更加復雜的運算(見圖2-2-2):

圖2-2-2 變量變換的示意案例

apply、applymap和map方法都可以向對象中的數據傳遞函數,主要區別如下:

● apply的操作對象是DataFrame的某一列(axis=0)或者某一行(axis=1);

● applymap的操作對象是元素級,作用于每個DataFrame的每個數據;

● map的操作對象也是元素級,但其是對Series中的每個數據調用一次函數。

2.2.6 表格的排序

我們可以使用np.sort()函數對向量進行排序處理。對于數據框,也可以使用sort_values()函數,根據數據框的某列數值對整個表進行排序。其中,ascending=False表示根據df的value列做降序處理,如dat_arrange2數據框所示(見圖2-2-3)。

圖2-2-3 表格排序的示意案例

2.2.7 表格的拼接

有時候,我們需要在已有數據框的基礎上添加新的行/列,或者橫向/縱向添加另外一個表格。此時我們需要使用pd.concat()函數或者append()函數實現該功能。先構造3個數據框,如下(見圖2-2-4)。

(1)數據框添加列或者橫向添加表格:

其中axis表示沿縱軸(axis=0)或者橫軸(axis=1)方向連接。(2)數據框添加行或者縱向添加表格:

圖2-2-4 表格拼接的示意案例

(3)可以添加行/列,也就可以刪除某行/列,這時需要使用*.drop()函數.比如要刪除df1的"y"列:

其中,labels就是要刪除的行/列的名字,用列表給定;axis默認為0,指刪除行,因此刪除columns時要指定axis=1;index直接指定要刪除的行;columns直接指定要刪除的列;inplace=False,默認該刪除操作不改變原數據,而是返回一個執行刪除操作后的新DataFrame;inplace=True,則會直接在原數據上進行刪除操作,且刪除后無法返回。

2.2.8 表格的融合

有時候,兩個數據框并沒有很好地保持一致。若不一致,則不能簡單地直接拼接。所以它們需要一個共同的列(common key)作為融合的依據。在表格的融合中,最常用的函數是pd.merge()函數。我們首先構造4個數據框如下(見圖2-2-5):

圖2-2-5 表格融合的示意案例

通過設定pd.merge()函數的不同參數可以實現不同的表格融合效果。其中,兩個表格融合會用缺失值NA代替不存在的值(見圖2-2-6和圖2-2-7)。

圖2-2-6 pd.merge()函數融合表格的示意案例

圖2-2-7 復雜的pd.merge()函數融合表格的示意案例

● 只保留左表的所有數據:

● 只保留右表的所有數據:

● 只保留兩個表中公共部分的信息:

● 保留兩個表的所有信息:

● on=["x","y"]表示多列匹配:

● left_on="x",right_on="g"可以根據兩個表的不同列名合并:

● 如果在表合并的過程中,兩個表有一列同名,但是值不同,合并時又都想保留下來,就可以用suffixes給每個表的重復列名增加后綴:

2.2.9 表格的分組操作

數據框往往存在某列包含多個類別的數據,如df.x包含A、B和C三個不同類別的數據,df_melt.year包含2010和2011兩個類別的數據。我們有時需要對數據框的列或者行,亦或者按數據類別進行分類運算等,此時數據的分組操作就尤為重要。先構造兩個數據框如下(見圖2-2-8):

圖2-2-8 對數據框按行或列求和

使用df_melt.info()函數可查看df_melt的數據信息,如圖2-2-9所示。可以發現year是object數據類型,如果需要將year變成int格式,則需要:

圖2-2-9 df_melt的數據信息

1.按行或列操作

● 按行求和:

● 按列求和:

● 單列運算:在Pandas中,DataFrame的一列就是一個Series,可以通過map或者apply函數來對某一列進行操作。

● 多列運算:要對DataFrame的多個列同時進行運算,可以使用apply()函數。

2.分組操作:groupby()函數

● 按year分組求均值,如圖2-2-10所示:

圖2-2-10 按year分組求均值

● 按year和x兩列變量分組求均值,如圖2-2-11所示:

圖2-2-11 按year和x兩列變量分組求均值

其中,as_index=False不會將['year','x']兩列設定為索引列。

● 按year分組求和:

● 按year分組求方差:

3.分組聚合:aggregate()函數

aggregate()函數結合groupby()函數可以實現SQL中的分組聚合運算,如圖2-2-12所示。aggregate()函數也可以簡寫為agg()。

圖2-2-12 aggregate分組聚結果

4.分組運算:transform()函數

transform()函數可以結合groupby來方便地實現類似SQL中的分組運算的操作。

5.分組篩選:filter()函數

filter()函數可以結合groupby來方便地實現類似SQL中的分組篩選運算的操作。

2.2.10 數據的導入與導出

大部分時候我們都是直接導入外部保存的數據文件,再使用它來繪制圖表。此時,就需要借助數據導入函數導入不同格式的數據,包括CSV、TXT、Excel、SQL、HTML等格式的文件。有時,我們也需要將處理好的數據從Python中導出保存。其中,我們在數據可視化中使用最多的就是前3種格式的數據文件。

(1)CSV格式數據的導入與導出

使用pd.read_csv()函數,可以讀入CSV格式的數據,并以DataFrame形式存儲。根據所讀取的數據文件編碼格式設置encoding參數,如utf8、ansi和gbk等編碼方式,當導入的數據存在中文字符時,要尤為注意。根據所讀取的數據文件列之間的分隔方式設定delimiter參數,大于一個字符的分隔符被看作正則表達式,如一個或者多個空格(\s+)、tab符號(\t)等。

使用to_csv()函數,可以將DataFrame的數據存儲為CSV文件:

index=False,表示忽略索引信息;index=True,表示輸出文件的第一列保留索引值。

CSV文件的特點主要有以下幾個:①文件結構簡單,基本上和TXT文本文件的差別不大;②可以和Excel進行轉換,這是一個很大的優點,很容易進行查看模式轉換,但是其文件存儲大小比Excel小。③簡單的存儲方式,可以減少存儲信息的容量,有利于網絡傳輸及客戶端的再處理;同時由于是一堆沒有任何說明的數據,具備基本的安全性。相比TXT和Excel數據文件,筆者推薦使用CSV格式的數據文件,進行導入與導出操作。

(2)TXT格式數據的導入與導出

如果將電子表格存儲在TXT文件中,可以使用np.loadtxt()函數加載數據。需要注意的是:TXT文本文件中的每一行必須含有相同數量的數據。使用np.loadtxt()函數可以讀取數據并存儲為ndarray數組,再使用pd.DataFrame()函數可以轉換為DataFrame格式的數據。其中,np.loadtxt()函數中的參數delimiter表示分隔符,默認為空格。

使用numpy.savetxt(fname,X)函數可以將ndarray數組保存為TXT格式的文件,其中參數fname為文件名,參數X為需要保存的數組(一維或者二維)。

(3)Excel格式數據的導入與導出

我們可以使用pd.read_excel()和to_excel()函數分別讀取與導出Excel格式的數據:

其中,sheetname指定頁面sheet,默認為0;header指定列名行,默認為0,即取第一行,數據為列名行以下的數據;若數據不含列名,則設定header=None。

其中,excel_writer表示目標路徑;index=False表示忽略索引列。

需要注意的是:使用plotnine包繪制圖表或者pandas包處理數據時,通常使用一維數據列表的數據框。但是如果導入的數據表格是二維數據列表,那么我們需要使用pd.melt()函數,可以將二維數據列表的數據框轉換成一維數據列表。

一維數據列表和二維數據列表的區別

一維數據列表就是由字段和記錄組成的表格。一般來說字段在首行,下面每一行是一條記錄。一維數據列表通常可以作為數據分析的數據源,每一行代表完整的一條數據記錄,所以可以很方便地進行數據的錄入、更新、查詢、匹配等,如圖2-2-13所示。

圖2-2-13 一維數據列表

二維數據列表就是行和列都有字段,它們相交的位置是數值的表格。這類表格一般是由分類匯總得來的,既有分類,又有匯總,所以是通過一維數據列表加工處理過的,通常用于呈現展示,如圖2-2-14所示。

圖2-2-14 二維數據列表

一維數據列表也常被稱為流水線表格,它和二維數據列表做出的數據透視表最大的區別在于“行總計”。判斷數據是一維數據列表還是二維數據列表的一個最簡單的辦法,就是看其列的內容:每一列是否是一個獨立的參數。如果每一列都是獨立的參數,那就是一維數據列表;如果每一列都是同類參數,那就是二維數據列表。

注意,為了后期更好地創建各種類型的數據透視表,建議用戶在錄入數據時,采用一維數據列表的形式,避免采用二維數據列表的形式。

2.2.11 缺失值的處理

導入的數據有時存在缺失值。另外,在統計與計算中,缺失值也不可避免,也起著至關重要的作用。Python使用np.nan表示缺失值。Pandas包也提供了諸多處理缺失值的函數與方法(見表2-2-6)。

表2-2-6 缺失值的處理

主站蜘蛛池模板: 固镇县| 岫岩| 无棣县| 荣成市| 乌鲁木齐市| 陆河县| 板桥市| 齐齐哈尔市| 呈贡县| 保亭| 长武县| 西畴县| 仁布县| 张掖市| 揭西县| 卢氏县| 松溪县| 大兴区| 洛隆县| 奉化市| 镇原县| 邵东县| 海伦市| 礼泉县| 天峨县| 余干县| 宾阳县| 固镇县| 改则县| 梨树县| 天津市| 汉寿县| 洛南县| 东光县| 安远县| 工布江达县| 昌邑市| 云龙县| 卓资县| 十堰市| 汕头市|