# 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)看到安裝說明。

* 以安裝於Windows環境為例,請在cmd(命令提示字元)輸入```pip install pandas```。

* 安裝成功後,我們試著載入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```進行資料整理與探勘。