2018/12/16

panda 資料處理簡介

16 panda 資料處理簡介

panda是python的一種外掛資料處理的函數庫,可用於處理結構化的資料。一般最常見的資料儲格式可能就是純文字的cvs格式、微軟的excel 格式、SQL 資料庫格式,panda 可讓我們處理這些格式的資料檔案。此外,panda亦可將資料存成一維的Series 或二維的 DataFrame 格式, 用來處理資料,如增刪、比較、運算等。Python 亦常用於和其他如Numpy, Scipy, matplotlib, scikit-learn 等函數庫結合,可組成強大的功能。

在機器學習的領域裡一般最常用的panda 功能是用來讀進檔案裡的資料,並組成 DataFrame 的格式,DataFrame 指的是資料訊框,顧名思義是資料有個框,是一種二維的資料格式,列是指每一筆資料,這在機器學習 (ML) 領域就是指一個實例 (instance),行(或欄)是指每一筆資料的不同屬性,在 ML 就是指每個實例 的不同特徵。這些資料常用各種不同的檔案格式儲存,而最常見的是儲存成純文字的cvs格式,但有很多不同的儲存方式,所以要讀進時要先對檔案儲存的方式有所了解。幾個要了解的重點是檔案裡有沒有列的index (索引)?各個行是否有給定行的名稱,如果有一般要放在第一列,數據和數據間如何分隔(一般最常見的是逗號 ',' ,有時也見分號 ';' 或是純空隔 ' ' ,是不是有換行符號等),這些區別對正讀進資料是很重要的,所以要謮進資料前要事先了解。

⬛ 讀進csv檔
我們以參考文獻裡的一個資料集檔案為例,此檔名為DogCat.csv,用常用的純文字程式編輯軟體如Notepad++打開,
Plays fetch,Is grumpy,Bacon,Dog food,Cat food,Species
Yes,No,Yes,No,No,Dog
No,Yes,No,Yes,No,Dog
No,Yes,No,No,Yes,Cat
No,Yes,Yes,No,No,Cat
.................
可見第一列是各欄(行)的名稱,但並沒有列的索引編號,資料的內文用逗號分開,且已有分行符號。
import numpy as np
import pandas as pd
df = pd.read_csv("DogCat.csv", header = 0)
print(df)
Plays fetch Is grumpy Bacon Dog food Cat food Species
0          Yes        No   Yes       No       No     Dog
1           No       Yes    No      Yes       No     Dog
2           No       Yes    No       No      Yes     Cat
3           No       Yes   Yes       No       No     Cat
4           No        No    No       No      Yes     Cat
5           No       Yes   Yes       No       No     Cat
6           No       Yes    No       No      Yes     Cat
7           No        No    No      Yes       No     Dog
8           No       Yes    No       No      Yes     Cat
9          Yes        No    No      Yes       No     Dog
10         Yes        No   Yes       No       No     Dog
11          No        No    No       No      Yes     Cat
12         Yes       Yes    No       No      Yes     Cat
13         Yes       Yes   Yes       No       No     Dog
14         Yes        No   Yes       No       No     Dog
15         Yes       Yes    No      Yes       No     Dog
16          No       Yes    No      Yes       No     Cat
17          No       Yes   Yes       No       No     Cat
18          No        No    No       No      Yes     Cat
panda的read_cvs() class 可讓我們讀進cvs檔案,constructor 中是"DogCat.csv"是指檔案放在jupyter notebook 工作目錄下,若永在其目錄要指定出路徑,而 header = 0是指欄位名稱放在第 0列,另因檔案沒有列的索引,pd 自動加上整數編號當為索引值。如果我們把修改成下列內容
Yes;No;Yes;No;No;Dog
No;Yes;No;Yes;No;Dog
No;Yes;No;No;Yes;Cat
No;Yes;Yes;No;No;Cat
No;No;No;No;Yes;Cat
要讀進此檔案就是
df2 = pd.read_csv("DogCat2.csv", header = None, sep=';')
print(df2)
 0    1    2    3    4    5
0  Yes   No  Yes   No   No  Dog
1   No  Yes   No  Yes   No  Dog
2   No  Yes   No   No  Yes  Cat
3   No  Yes  Yes   No   No  Cat
4   No   No   No   No  Yes  Cat
因檔案中沒有欄位名稱,且內容是以';'分開,所以在constructor 中就要指定 header = None, sep=';',這樣才能正確讀進檔案。我們執下列程式看看
print(df2[1]) 
print(df2[1:2]) 
print(df2[1][1])
0     No
1    Yes
2    Yes
3    Yes
4     No
Name: 1, dtype: object
    0    1   2    3   4    5
1  No  Yes  No  Yes  No  Dog
Yes
若使用df[1],列印的是第1欄,若要列印第一列要用df2[1:2],df2[1][1]列印的是第1列且是第1行的內容。若我們想要把欄位名稱恢復和DogCat2.csv中的一樣,可用
df2.columns=['Plays fetch','Is grumpy','Bacon',
             'Dog food','Cat food','Species']
df2

加入欄位名稱
可見欄位名稱改變了,且jupyter notebook 幫我們以表格的形式排得很整齊。相似的方法也可用於改變索引標號,需注意的是列索引不只限定整數,任何數字文字都可以,我們試著改用文字,稍後可再改回整數。
df2.index=['one','two','three','four','five']
df2
更改索引
可見索引以改成文字形式。現在列和欄的名稱都是文字,要取出欄的內容如下
print(df2['Plays fetch'])
print(df2.Species)
one      Yes
two       No
three     No
four      No
five      No
Name: Plays fetch, dtype: object
one      Dog
two      Dog
three    Cat
four     Cat
five     Cat
Name: Species, dtype: object
需注意的是若要用物件加欄位名稱的方法,如上df2.Species,則必需是名稱為合法的python 變數,否則會報錯,如 df2.Plays fetch 是錯誤的用法。若要取出列可使用
df2['two':'three']

文字索引取出多
注意用文字索引時是「前閉後閉」也就是列在索引中的項目都取出,不像整數索引是「前閉後開」也就是不包括最後一項,但文字索引因最後一列再上去沒有任何名稱可參考,若沒包括最後項就沒辦法取出最後項。Python 整數索引範圍不包括最後項很奇怪!如果要取出多行可用
df2[['Cat food','Species']]
文字索引取出多行
我們可以把索引改回整數,
ind =pd.Index(range(5))
df2.index=ind
df2
回復整索引
上面的已討論到取出行或列的單行或單列,若要取出部份行及部份列所對應到的內容,較方便的用是叫iloc方法,如
df2.iloc[3:5,1:3]
    Is grumpy Bacon
3 Yes Yes
4 No No
注意切分 (slicing) 是「上開」,就是不包括最高的整數項。

⬛ 修改內容
上列表格中都是文字 ,含Yes, No, Dog, Cat,若希望更改某個元素的內容可先選定該元素再行指配就可以,若希望全部改成二元形式可用mpa() 方法,如
d = {'Yes': 1, 'No': 0}
df2['Plays fetch'] = df2['Plays fetch'].map(d)
df2['Is grumpy'] = df2['Is grumpy'].map(d)
df2['Bacon'] = df2['Bacon'].map(d)
df2['Dog food'] = df2['Dog food'].map(d)
df2['Cat food'] = df2['Cat food'].map(d)
d = {'Dog': 1, 'Cat': 0}
df2['Species'] = df2['Species'].map(d)
df2.head()
整批修改內容
先定一個python 的 dict ,再用map()方法依序將每個欄位的內容用map() 依dict的定義進行對應,相當方便。

⬛ 儲存到csv檔
可將處理中載於記憶體的DataFrame 以csv格式存檔,如
df2.to_csv('test1.csv',index=False,header=False)
上列指令是將df2的內容存到test1.csv檔裡,若用Notepad++打開可見
1,0,1,0,0,1
0,1,0,1,0,1
0,1,0,0,1,0
0,1,1,0,0,0
0,0,0,0,1,0
因指定無index,也無header,所以檔中只存DataFrame內容,沒有存index 及header。若改成
df2.to_csv('test2.csv')
儲存的內容會是
,Plays fetch,Is grumpy,Bacon,Dog food,Cat food,Species
0,1,0,1,0,0,1
1,0,1,0,1,0,1
2,0,1,0,0,1,0
3,0,1,1,0,0,0
4,0,0,0,0,1,0
⬛ 儲存到csv檔
假設已用excel建立一個檔句datafile.xlsx,則可
df3 = pd.read_excel("datafile.xlsx")
df3
讀進excel檔
用read_excel 可讀進excel檔。 ⬛ 建立Series 和 DataFrame 物件 上面討論都是從檔案讀進資料並存成 DataFrame物件,但在程式中有時也可能需要自行建立物作。Series 是一維物件,亦即只有一個欄位的資料和索,而DataFrame是二維物件,一維是索引,另一維可存放多個欄位。panda 裡的索臣較具彈性,如果在建立物件時沒有指定特定格式的索引,panda會像Numpy 的array 一樣自動建由0開始自動增加的整數索引,如下可建立一維的Series
ser1=pd.Series([2, 4, 6,8,10])
ser1
0     2
1     4
2     6
3     8
4    10
dtype: int64
上列中可見沒有指定index給Series時,產生的物件自動加上整數index,從9開始。假設我們希望由2開始,可以用
index = range(2,7)
# ser1=pd.Series([2, 4, 6,8,10], index = index)
# ser1=pd.Series([2, 4, 6,8,10], index = [2,3,4,5,6])
ser1=pd.Series([2, 4, 6,8,10], index = range(2,7))
ser1
2     2
3     4
4     6
5     8
6    10
dtype: int64
上述中註解掉的兩行也可分別用來產生相同的序列。若想在序列中使用文字的索引,可如下
index = ['one','two','three','four','five']
ser1=pd.Series([2, 4, 6,8,10], index = index)
ser1
one       2
two       4
three     6
four      8
five     10
dtype: int64
可見index 確是變成文字了。
若想建立二維的DataFrame,方法類,如下
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002, 2003],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
df4 = pd.DataFrame(data)
df4
新增DataFrame
若想更改索引可用和之前討論過的方法更改,這就建立了想要的DataFrame 物件了 。
panda的功能相當多,各項操作可參考線上文件或專書,簡介就到此結束。

參考文獻
Gavin Hackeling, Mastering Machine Learning with scikit-learn, 2nd, Packt Publishing, 2017

沒有留言:

張貼留言