# Lesson 6 | DataFrame簡介與資料清理 ## 第一節:Pandas簡介(1) * 我們在第三堂課已經介紹了使用第三方套件[NumPy](https://numpy.org/)來處理二維、三維或是高維的資料。 * 但NumPy所創建的矩陣有個不方便的限制,就是矩陣內的資料型態必須是一致的,然而,在實際在分析資料時,每個欄位(變數或特徵)的資料型態很少都是一樣的,就如在第五堂課的資料範例中,同時會有字串(病歷號)以及數字(左心室射出率)的欄位。 ## 第一節:Pandas簡介(2) * 接下來,我們將帶領著同學使用另一個常用的第三方套件[Pandas](https://pandas.pydata.org/)來進行資料前處理與分析。 * 同樣的我們也可以在其[官方網站](https://pandas.pydata.org/docs/getting_started/index.html)看到安裝說明。 ![L6-1](https://i.imgur.com/Lk80wRX.png) * 以安裝於Windows環境為例,請在cmd(命令提示字元)輸入```pip install pandas```。 ![L6-2](https://i.imgur.com/pcCrlcS.png) * 安裝成功後,我們試著載入Pandas套件。 ```python= import pandas as pd ``` ## 第一節:Pandas簡介(3) * Pandas的方便之處在於可以透過其高階函式來進行檔案讀取以及資料索引。 * 還記得我們第三堂課所整理的資料嗎? * 請按[這裡](https://linchin.ndmctsgh.edu.tw/data/monitoring_1.csv)下載等等要讀取的檔案,並放到工作目錄下。 * 這個檔案是105年4月25日早上5點30台北市各監測站,各空氣汙染物濃度的檔案。 * 我們將對這個檔案進行資料清理。 * 在這堂課,我們將試著透過第三方套件```Pandas```來進行資料處理。 ## 第一節:Pandas簡介(4) * 透過Pandas讀取csv檔是非常簡單的事情,程式碼如下。 ```python= data = pd.read_csv("monitoring_1.csv", encoding = 'CP950') ``` * 稍微觀察一下其資料型態,Python告訴我們這個變數的資料型態是DataFrame(資料表)。 ```python= print(type(data)) ``` * 接著我們可以直接```print()```資料,或是利用```Pandas```的高階方法,進行快速的資料檢視。 ```python= print(data) ``` * 觀察前五筆資料 ```python= print(data.head(5)) ``` ## 第一節:Pandas簡介(5) * 若我們要將檔案寫出呢?用這樣的方式就可以輕鬆將檔案寫出。 ```python= data.to_csv('monitoring_1_wback.csv', encoding = 'CP950') ``` * 同學們可以發現,不是每個程式任務都需要自己造輪子,但經過先前的課程,同學們其實已有能力透過Basic Python Code來完成絕大部分的事情。 ## 練習1: * 不知道大家有沒有發現,我們所寫出的檔案,有行的名稱(row names,或是稱index),請同學們練習看[官方說明](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_csv.html),幫我查詢一下如何寫出csv檔案時不要有row names。 <details> <summary>解答</summary> - ```.to_csv()```的index參數預設為```True```,我們將輸入參數index改為```False```即可。 ```python= data.to_csv('monitoring_1_wback.csv', index = False, encoding = 'CP950') ``` </details> ## 第二節:Pandas與資料清理(1) * 還記得之前的練習嗎?我們使用迴圈檢查這份空氣汙染資料有多少筆重複資料,清除後寫出。 * 在進行之前,讓我們先一步一的練習如何呼叫與索引```Pandas```的```DataFrame```。 * 類似於```NumPy```我們可以用下列方法觀察其```DataFrame```。 ```python= # 回傳資料表行數與列數。 print(data.shape) # 回傳資料表的row names。 print(data.index) # 回傳資料表的column names。 print(data.columns) ``` ## 第二節:Pandas與資料清理(2) * 接著,讓我們先試著取出各欄位資料。 * 譬如說只取時間這個欄位。 ```python= print(data['time']) ``` * 也可以透過迴圈來一個一個地取出資料。 ```python= for i in data['time']: print(i) ``` * 若我們要取多個欄位呢,我們可以在索引的部分放入list。 ```python= # 注意,這樣的取值得到的是一個新的DataFrame sub_data = data[['time', 'school']] print(sub_data) print(type(sub_data)) ``` ## 第二節:Pandas與資料清理(2) * ```Pandas```的```DataFrame```支援與Basic Python還有```NumPy```相似的索引邏輯。 * 例如取出某欄位的方式如下: ```python= # 取出第一個值 print(data['school'][0]) # 取出第二到第四個值 print(data['school'][1:5]) ``` * 當然也支援條件判斷式的索引: ```python= print([data['school'] == "興隆國小"]) print(data['school'][data['school'] == "興隆國小"]) ``` ## 第二節:Pandas與資料清理(3) * 回到我們想要找出重複資料的部分,稍微思考一下,加上迴圈我們就可以很簡單做到。 * 這些程式碼幫助同學理解如何思考迴圈。 ```python= i = 1 print(data['school'][i]) print(data['school'][0:i]) print(data['school'][i] in data['school'][0:i].tolist()) i = 2 print(data['school'][i]) print(data['school'][0:i]) print(data['school'][i] in data['school'][0:i].tolist()) ``` * 接著用迴圈來尋找重複的欄位。 ```python= # 先創建儲存結果的list duplicate = [False] * len(data.index) # 主要迴圈 for i in data.index: if data['school'][i] in data['school'][0:i].tolist(): print(data['school'][i]) duplicate[i] = True # 接著貼回去DataFrame data['duplicated'] = duplicate print(data) ``` ## 第二節:Pandas與資料清理(4) * 但事實上,這是在資料清理時非常常遇到的問題,Pandas也有專門的函式在處理重複的問題。 * 在[官方文件](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.duplicated.html)中可以找到```.duplicated()```這個方法。 ```python= data.duplicated() # 結果我們發現全部都是False ``` * 仔細看官方說明,可以發現我們應該要輸入參數指定特定欄位。 ```python= # 我們可以用相同於索引的方式來創建新欄位。 data['dulpicate_2'] = data.duplicated(subset = 'school') print(data) ``` * 那我們要怎麼索引特定行數呢?還記得```NumPy```組合條件判斷與索引的方式嗎?```Pandas```也是類似的邏輯。 ```python= # 我們呼叫特定欄位後可以對其進行判斷 print(data['dulpicate_2'] == False) # 接著我們可以索引整個DataFrame print(data[data['dulpicate_2'] == False]) ``` * 是不是很簡單呢?我們接著就可以把整理過後的檔案寫出了。 ```python= final_data = data[data['dulpicate_2'] == False] final_data.to_csv('monitoring_2.csv', index = False, encoding = 'CP950') ``` ## 練習2: * 寫出檔案後我們發現了一個問題:其實我們不需要```dulpicate```與```dulpicate_2```,請同學們試著移除這兩個欄位後重新寫出檔案。 * 提示:可以藉由索引特定欄位名稱,來去除我們不要的欄位。 <details> <summary>解答</summary> ```python= final_data = data[data['dulpicate_2'] == False] final_data = final_data[['time', 'device_id', 's_d0', 's_t0', 's_h0', 'lat', 'lon', 'school', 'time2']] final_data.to_csv('monitoring_2.csv', index = False, encoding = 'CP950') ``` </details> ## 總結 * 本次課程介紹了新的第三方套件```Pandas```與新的資料型態```DataFrame```。 * 利用第三方套件能更快速的執行我們想要的任務,但請同學們不要忘了如何撰寫Basic Python Code。 * ```Pandas```是非常常用來進行資料清理與資料分析的套件,在接下來的課程中,會讓同學們更進一步地熟悉以```Pandas```進行資料整理與探勘。