用一個月整理的Pandas的教程!最全面的教程沒有之一!先收藏吧!

weixin_34292287發表於2018-12-26

Pandas是基於NumPy的一個開源 Python 庫,它被廣泛用於快速分析資料,以及資料清洗和準備等工作。它的名字來源是由“ Panel data”(皮膚資料,一個計量經濟學名詞)兩個單詞拼成的。簡單地說,你可以把 Pandas 看作是 Python 版的 Excel。

12649257-e25bd40655ad7f9d

我喜歡 Pandas 的原因之一,是因為它很酷,它能很好地處理來自一大堆各種不同來源的資料,比如 Excel 表格、CSV 檔案、SQL 資料庫,甚至還能處理儲存在網頁上的資料。

話不多說,讓我們開始吧!

安裝 Pandas

進群:當然入門Python沒有好的學習資料怎麼行呢?所以小編這裡準備了一份Python學習資料,新增小編學習交流群943752371即可

如果你已經安裝了 Anaconda,你可以很方便地在終端或者命令提示符裡輸入命令安裝 Pandas:

12649257-a5e5452ec23293ba

如果你還沒安裝 Anaconda,你也可以用 Python 自帶的包管理工具 pip 來安裝:

12649257-3db8eb1035b4b43a

Pandas 資料結構

Series 是一種一維陣列,和 NumPy 裡的陣列很相似。事實上,Series 基本上就是基於 NumPy 的陣列物件來的。和 NumPy 的陣列不同,Series 能為資料自定義標籤,也就是索引(index),然後通過索引來訪問陣列中的資料。

12649257-080122c356cc645c

建立一個 Series 的基本語法如下:

need-to-insert-img

上面的 data 引數可以是任意資料物件,比如字典、列表甚至是 NumPy 陣列,而index 引數則是對 data 的索引值,類似字典的 key。

下面這個例子裡,將建立一個 Series 物件,並用字串對數字列表進行索引:

need-to-insert-img

注意:請記住, index 引數是可省略的,你可以選擇不輸入這個引數。如果不帶 index 引數,Pandas 會自動用預設 index 進行索引,類似陣列,索引值是 [0, ..., len(data) - 1] ,如下所示:

從 NumPy 陣列物件建立 Series:

12649257-779627885fc6afe6

從 Python 字典物件建立 Series:

12649257-2d0385e6af38c86b

如上圖的 out[24] 中所示,如果你從一個 Python 字典物件建立 Series,Pandas 會自動把字典的鍵值設定成 Series 的 index,並將對應的 values 放在和索引對應的 data 裡。

和 NumPy 陣列不同,Pandas 的 Series 能存放各種不同型別的物件。

從 Series 裡獲取資料

訪問 Series 裡的資料的方式,和 Python 字典基本一樣:

12649257-ae49500c6838523b

對 Series 進行算術運算操作

對 Series 的算術運算都是基於 index 進行的。我們可以用加減乘除(+ - * /)這樣的運算子對兩個 Series 進行運算,Pandas 將會根據索引 index,對響應的資料進行計算,結果將會以浮點數的形式儲存,以避免丟失精度。

12649257-11a6c21629230bbd

如上,如果 Pandas 在兩個 Series 裡找不到相同的 index,對應的位置就返回一個空值 NaN。

DataFrames

Pandas 的 DataFrame(資料表)是一種 2 維資料結構,資料以表格的形式儲存,分成若干行和列。通過 DataFrame,你能很方便地處理資料。常見的操作比如選取、替換行或列的資料,還能重組資料表、修改索引、多重篩選等。

構建一個 DataFrame 物件的基本語法如下:

舉個例子,我們可以建立一個 5 行 4 列的 DataFrame,並填上隨機資料:

看,上面表中的每一列基本上就是一個 Series ,它們都用了同一個 index。因此,我們基本上可以把 DataFrame 理解成一組採用同樣索引的 Series 的集合。

下面這個例子裡,我們將用許多 Series 來構建一個DataFrame:

12649257-6f14529566ffb6e4

以及用一個字典來建立 DataFrame:

12649257-8ebd9676e94e6f11

獲取 DataFrame 中的列

要獲取一列的資料,還是用中括號 [] 的方式,跟 Series 類似。比如嘗試獲取上面這個表中的 name 列資料:

12649257-952c68e5958ed3e7

因為我們只獲取一列,所以返回的就是一個 Series。可以用 type() 函式確認返回值的型別:

12649257-ebf1b40f9a8a220b

如果獲取多個列,那返回的就是一個 DataFrame 型別:

12649257-7ee0057154749745

向 DataFrame 裡增加資料列

建立一個列的時候,你需要先定義這個列的資料和索引。舉個例子,比如這個 DataFrame:

12649257-f633823916a949d9

增加資料列有兩種辦法:可以從頭開始定義一個 pd.Series,再把它放到表中,也可以利用現有的列來產生需要的新列。比如下面兩種操作:

定義一個 Series ,並放入 'Year' 列中:

12649257-a87fc2735188e1f0

從現有的列建立新列:

12649257-8c98629d5bebe9f3

從 DataFrame 裡刪除行/列

想要刪除某一行或一列,可以用 .drop() 函式。在使用這個函式的時候,你需要先指定具體的刪除方向,axis=0 對應的是行 row,而 axis=1 對應的是列 column 。

刪除 'Birth_year' 列:

12649257-461ad6fe116f007a

刪除 'd' 行:

12649257-9bdb64db36433fdd

請務必記住,除非使用者明確指定,否則在呼叫 .drop() 的時候,Pandas 並不會真的永久性地刪除這行/列。這主要是為了防止使用者誤操作丟失資料。

你可以通過呼叫 df 來確認資料的完整性。如果你確定要永久性刪除某一行/列,你需要加上 inplace=True 引數,比如:

12649257-ed50e98164a183bf

獲取 DataFrame 中的一行或多行資料

要獲取某一行,你需要用 .loc[] 來按索引(標籤名)引用這一行,或者用 .iloc[],按這行在表中的位置(行數)來引用。

12649257-87d6a2cef9baeceb

同時你可以用 .loc[] 來指定具體的行列範圍,並生成一個子資料表,就像在NumPy裡做的一樣。比如,提取 'c' 行中 'Name’ 列的內容,可以如下操作:

12649257-87413cc4d333a49a

此外,你還可以制定多行和/或多列,如上所示。

條件篩選

用中括號 [] 的方式,除了直接指定選中某些列外,還能接收一個條件語句,然後篩選出符合條件的行/列。比如,我們希望在下面這個表格中篩選出 'W'>0 的行:

12649257-3e9f4fd1be8c418d

如果要進一步篩選,只看 'X' 列中 'W'>0 的資料:

12649257-a76808b88b2bc276

類似的,你還可以試試這樣的語句 df[df['W']>0][['X','Y']] ,結果將會是這樣:

上面那行相當於下面這樣的幾個操作連在一起:

12649257-4ea21025b05f53a6

你可以用邏輯運算子 &(與)和 |(或)來連結多個條件語句,以便一次應用多個篩選條件到當前的 DataFrame 上。舉個例子,你可以用下面的方法篩選出同時滿足 'W'>0 和'X'>1 的行:

12649257-2ed8ab5d247bdfb5

重置 DataFrame 的索引

如果你覺得當前 DataFrame 的索引有問題,你可以用 .reset_index() 簡單地把整個表的索引都重置掉。這個方法將把目標 DataFrame 的索引儲存在一個叫 index 的列中,而把表格的索引變成預設的從零開始的數字,也就是 [0, ..., len(data) - 1] 。比如下面這樣:

need-to-insert-img

和刪除操作差不多,.reset_index() 並不會永久改變你表格的索引,除非你呼叫的時候明確傳入了 inplace 引數,比如:.reset_index(inplace=True)

設定 DataFrame 的索引值

類似地,我們還可以用 .set_index() 方法,將 DataFrame 裡的某一列作為索引來用。比如,我們在這個表裡新建一個名為 "ID" 的列:

12649257-c95669e796bf8801

然後把它設定成索引:

12649257-561a0547c1cba94a

注意,不像 .reset_index() 會保留一個備份,然後才用預設的索引值代替原索引,.set_index() 將會完全覆蓋原來的索引值。

多級索引(MultiIndex)以及命名索引的不同等級

多級索引其實就是一個由元組(Tuple)組成的陣列,每一個元組都是獨一無二的。你可以從一個包含許多陣列的列表中建立多級索引(呼叫 MultiIndex.from_arrays ),也可以用一個包含許多元組的陣列(呼叫 MultiIndex.from_tuples )或者是用一對可迭代物件的集合(比如兩個列表,互相兩兩配對)來構建(呼叫MultiIndex.from_product )。

下面這個例子,我們從元組中建立多級索引:

12649257-7ae496b922430839

最後這個 list(zip()) 的巢狀函式,把上面兩個列表合併成了一個每個元素都是元組的列表。這時 my_index 的內容是這樣的:[('O Level', 21), ('O Level', 22), ('O Level', 23), ('A Level', 21), ('A Level', 22), ('A Level', 23)]

接下來,我們呼叫 .MultiIndex.from_tuples(my_index) 生成一個多級索引物件:

12649257-c89032752c91e5c1

最後,將這個多級索引物件轉成一個 DataFrame:

12649257-0694b86ff2b6d762

要獲取多級索引中的資料,還是用到 .loc[] 。比如,先獲取 'O Level' 下的資料:

12649257-8da2efdeaf5059d6

然後再用一次 .loc[],獲取下一層 21 裡的資料:

12649257-6be4b77b22e41861

如上所示,df 這個 DataFrame 的頭兩個索引列沒有名字,看起來不太易懂。我們可以用 .index.names 給它們加上名字:

12649257-b011b78c7617cb50

交叉選擇行和列中的資料

我們可以用 .xs() 方法輕鬆獲取到多級索引中某些特定級別的資料。比如,我們需要找到所有 Levels 中,Num = 22 的行:

12649257-9b8984cc07d88174

清洗資料

刪除或填充空值

在許多情況下,如果你用 Pandas 來讀取大量資料,往往會發現原始資料中會存在不完整的地方。在 DataFrame 中缺少資料的位置, Pandas 會自動填入一個空值,比如 NaN或 Null 。因此,我們可以選擇用 .dropna() 來丟棄這些自動填充的值,或是用.fillna() 來自動給這些空值填充資料。

比如這個例子:

12649257-9923a4a9c2f06284

當你使用 .dropna() 方法時,就是告訴 Pandas 刪除掉存在一個或多個空值的行(或者列)。刪除列用的是 .dropna(axis=0) ,刪除行用的是 .dropna(axis=1) 。

請注意,如果你沒有指定 axis 引數,預設是刪除行。

刪除行:

12649257-9fa9cdb5870ee207

刪除列:

12649257-d8b9dc94a2d362a2

類似的,如果你使用 .fillna() 方法,Pandas 將對這個 DataFrame 裡所有的空值位置填上你指定的預設值。比如,將表中所有 NaN 替換成 20 :

12649257-e4609be6a255d2ba

當然,這有的時候打擊範圍太大了。於是我們可以選擇只對某些特定的行或者列進行填充。比如只對 'A' 列進行操作,在空值處填入該列的平均值:

12649257-333608d080d79a82

如上所示,'A' 列的平均值是 2.0,所以第二行的空值被填上了 2.0。

同理,.dropna() 和 .fillna() 並不會永久性改變你的資料,除非你傳入了inplace=True 引數。

Pandas是基於NumPy的一個開源 Python 庫,它被廣泛用於快速分析資料,以及資料清洗和準備等工作。它的名字來源是由“ Panel data”(皮膚資料,一個計量經濟學名詞)兩個單詞拼成的。簡單地說,你可以把 Pandas 看作是 Python 版的 Excel。

我喜歡 Pandas 的原因之一,是因為它很酷,它能很好地處理來自一大堆各種不同來源的資料,比如 Excel 表格、CSV 檔案、SQL 資料庫,甚至還能處理儲存在網頁上的資料。

分組統計

Pandas 的分組統計功能可以按某一列的內容對資料行進行分組,並對其應用統計函式,比如求和,平均數,中位數,標準差等等…

舉例來說,用 .groupby() 方法,我們可以對下面這資料表按 'Company' 列進行分組,並用 .mean() 求每組的平均值:

首先,初始化一個DataFrame:

12649257-a0036761fe9a419f

然後,呼叫 .groupby() 方法,並繼續用 .mean() 求平均值:

12649257-c93b599de8b11a5c

上面的結果中,Sales 列就變成每個公司的分組平均數了。

計數

用 .count() 方法,能對 DataFrame 中的某個元素出現的次數進行計數。

need-to-insert-img

資料描述

Pandas 的 .describe() 方法將對 DataFrame 裡的資料進行分析,並一次性生成多個描述性的統計指標,方便使用者對資料有一個直觀上的認識。

生成的指標,從左到右分別是:計數、平均數、標準差、最小值、25% 50% 75% 位置的值、最大值。

12649257-ea2c8e6a548f43a9

如果你不喜歡這個排版,你可以用 .transpose() 方法獲得一個豎排的格式:

12649257-80848ea6cbe21ebb

如果你只想看 Google 的資料,還能這樣:

12649257-a756fde71bba9dea

堆疊(Concat)

堆疊基本上就是簡單地把多個 DataFrame 堆在一起,拼成一個更大的 DataFrame。當你進行堆疊的時候,請務必注意你資料表的索引和列的延伸方向,堆疊的方向要和它一致。

比如,有這樣3個 DataFrame:

12649257-00dcf3897c607d0e

我們用 pd.concat() 將它堆疊成一個大的表:

12649257-658c246a5f468397

因為我們沒有指定堆疊的方向,Pandas 預設按行的方向堆疊,把每個表的索引按順序疊加。

如果你想要按列的方向堆疊,那你需要傳入 axis=1 引數:

12649257-8a69c3157c8a734c

注意,這裡出現了一大堆空值。因為我們用來堆疊的3個 DataFrame 裡,有許多索引是沒有對應資料的。因此,當你使用 pd.concat() 的時候,一定要注意堆疊方向的座標軸(行或列)含有所需的所有資料。

歸併(Merge)

使用 pd.merge() 函式,能將多個 DataFrame 歸併在一起,它的合併方式類似合併 SQL 資料表的方式。

歸併操作的基本語法是 pd.merge(left, right, how='inner', on='Key') 。其中 left 引數代表放在左側的 DataFrame,而 right 引數代表放在右邊的 DataFrame;how='inner' 指的是當左右兩個 DataFrame 中存在不重合的 Key 時,取結果的方式:inner 代表交集;Outer 代表並集。最後,on='Key' 代表需要合併的鍵值所在的列,最後整個表格會以該列為準進行歸併。

對於兩個都含有 key 列的 DataFrame,我們可以這樣歸併:

12649257-4be21b6e1e376623

同時,我們可以傳入多個 on 引數,這樣就能按多個鍵值進行歸併:

12649257-b4789ed6a81c2315

連線(Join)

如果你要把兩個表連在一起,然而它們之間沒有太多共同的列,那麼你可以試試 .join() 方法。和 .merge() 不同,連線採用索引作為公共的鍵,而不是某一列。

12649257-989bc1dcaa52cbe0

同樣,inner 代表交集,Outer 代表並集。

數值處理

查詢不重複的值

不重複的值,在一個 DataFrame 裡往往是獨一無二,與眾不同的。找到不重複的值,在資料分析中有助於避免樣本偏差。在 Pandas 裡,主要用到 3 種方法:

首先是 .unique() 方法。比如在下面這個 DataFrame 裡,查詢 col2 列中所有不重複的值:

12649257-bfc78df54aea324c

除了列出所有不重複的值,我們還能用 .nunique() 方法,獲取所有不重複值的個數:

12649257-0b74a4ff6215dde2

此外,還可以用 .value_counts() 同時獲得所有值和對應值的計數:

12649257-f66b4d21ccf94938

apply() 方法

用 .apply() 方法,可以對 DataFrame 中的資料應用自定義函式,進行資料處理。比如,我們先定義一個 square() 函式,然後對錶中的 col1 列應用這個函式:

12649257-d1180f994abb426b

在上面這個例子中,這個函式被應用到這一列裡的每一個元素上。同樣,我們也可以呼叫任意的內建函式。比如對 col3 列取長度 len :

12649257-c750803a34d84166

有的時候,你定義了一個函式,而它其實只會被用到一次。那麼,我們可以用 lambda 表示式來代替函式定義,簡化程式碼。比如,我們可以用這樣的 lambda 表示式代替上面 In[47] 裡的函式定義:

12649257-909f675776c2c0e8

獲取 DataFrame 的屬性

DataFrame 的屬性包括列和索引的名字。假如你不確定表中的某個列名是否含有空格之類的字元,你可以通過 .columns 來獲取屬性值,以檢視具體的列名。

12649257-16e02fc573c3ea25

排序

如果想要將整個表按某一列的值進行排序,可以用 .sort_values() :

12649257-b3fbe9fc17c4f80b

如上所示,表格變成按 col2 列的值從小到大排序。要注意的是,表格的索引 index 還是對應著排序前的行,並沒有因為排序而丟失原來的索引資料。

查詢空值

假如你有一個很大的資料集,你可以用 Pandas 的 .isnull() 方法,方便快捷地發現表中的空值:

12649257-b5dc3aee24734e71

這返回的是一個新的 DataFrame,裡面用布林值(True/False)表示原 DataFrame 中對應位置的資料是否是空值。

資料透視表

在使用 Excel 的時候,你或許已經試過資料透視表的功能了。資料透視表是一種彙總統計表,它展現了原表格中資料的彙總統計結果。Pandas 的資料透視表能自動幫你對資料進行分組、切片、篩選、排序、計數、求和或取平均值,並將結果直觀地顯示出來。比如,這裡有個關於動物的統計表:

12649257-5d38ebdef14969af

Pandas 資料透視表的語法是 .pivot_table(data, values='', index=[''], columns=['']) ,其中 values 代表我們需要彙總統計的資料點所在的列,index 表示按該列進行分組索引,而 columns 則表示最後結果將按該列的資料進行分列。你可以在 Pandas 的官方文件 中找到更多資料透視表的詳細用法和例子。

於是,我們按上面的語法,給這個動物統計表建立一個資料透視表:

12649257-a448016b95f1fbe5

或者也可以直接呼叫 df 物件的方法:

12649257-cf8fabd765e8a730

在上面的例子中,資料透視表的某些位置是 NaN 空值,因為在原資料裡沒有對應的條件下的資料。

匯入匯出資料

採用類似 pd.read_ 這樣的方法,你可以用 Pandas 讀取各種不同格式的資料檔案,包括 Excel 表格、CSV 檔案、SQL 資料庫,甚至 HTML 檔案等。

讀取 CSV 檔案

簡單地說,只要用 pd.read_csv() 就能將 CSV 檔案裡的資料轉換成 DataFrame 物件:

12649257-02b5bfeef4c1e4de

寫入 CSV 檔案

將 DataFrame 物件存入 .csv 檔案的方法是 .to_csv(),例如,我們先建立一個 DataFrame 物件:

12649257-919e99c51aa27bc7

然後我們將這個 DataFrame 物件存成 'New_dataframe' 檔案,Pandas 會自動在磁碟上建立這個檔案。

12649257-72170e9c87943d85

這裡傳入 index=False 引數是因為不希望 Pandas 把索引列的 0~5 也存到檔案中。

為了確保資料已經儲存好了,你可以試試用 pd.read_csv('New_dataframe') ,把這個檔案的內容讀取出來看看。

讀取 Excel 表格檔案

Excel 檔案是一個不錯的資料來源。使用 pd.read_excel() 方法,我們能將 Excel 表格中的資料匯入 Pandas 中。請注意,Pandas 只能匯入表格檔案中的資料,其他物件,例如巨集、圖形和公式等都不會被匯入。如果檔案中存在有此類物件,可能會導致 pd.read_excel() 方法執行失敗。

舉個例子,假設我們有一個 Excel 表格 'excel_output.xlsx',然後讀取它的資料:

12649257-398696f76db338d7

請注意,每個 Excel 表格檔案都含有一個或多個工作表,傳入 sheet_name='Sheet1' 這樣的引數,就表示只讀取 'excel_output.xlsx' 中的 Sheet1 工作表中的內容。

寫入 Excel 表格檔案

跟寫入 CSV 檔案類似,我們可以將一個 DataFrame 物件存成 .xlsx 檔案,語法是 .to_excel() :

12649257-1d97fb923a466d7d

和前面類似,把資料存到 'excel_output.xlsx' 檔案中:

12649257-24ba83292cb85136

讀取 HTML 檔案中的資料

為了讀取 HTML 檔案,你需要安裝 htmllib5,lxml 以及 BeautifulSoup4 庫,在終端或者命令提示符執行以下命令來安裝:

12649257-a0e55b66c864521b

舉個例子,我們用讓 Pandas 讀取這個頁面的資料: https://en.wikipedia.org/wiki/Udacity 。由於一個頁面上含有多個不同的表格,我們需要通過下標 [0, ..., len(tables) - 1] 訪問陣列中的不同元素。

下面的這個例子,我們顯示的是頁面中的第 2 個表格:

12649257-cb0c5cbdea1eb6c1

結語

恭喜!讀到這裡,說明你已經看完了這個教程!

如果你已經學完了本文,我想你應該已經擁有足夠的知識,可以好好調教 Pandas,做好分析之前的資料準備工作啦。接下來,你需要的是練習,練習,再練習!

相關文章