pandas | 使用pandas進行資料處理——DataFrame篇
今天是pandas資料處理專題的第二篇文章,我們一起來聊聊pandas當中最重要的資料結構——DataFrame。
上一篇文章當中我們介紹了Series的用法,也提到了Series相當於一個一維的陣列,只是pandas為我們封裝了許多方便好用的api。而DataFrame可以簡單了理解成Series構成的dict,這樣就將資料拼接成了二維的表格。並且為我們提供了許多表級別資料處理以及批量資料處理的介面,大大降低了資料處理的難度。
建立DataFrame
DataFrame是一個表格型的資料結構,它擁有兩個索引,分別是行索引以及列索引,使得我們可以很方便地獲取對應的行以及列。這就大大降低了我們查詢資料處理資料的難度。
首先,我們先從最簡單的開始,如何建立一個DataFrame。
從字典建立
我們建立了一個dict,它的key是列名,value是一個list,當我們將這個dict傳入DataFrame的建構函式的時候,它將會以key作為列名,value作為對應的值為我們建立一個DataFrame。
當我們在jupyter輸出的時候,它會自動為我們將DataFrame中的內容以表格的形式展現。
從numpy資料建立
我們也可以從一個numpy的二維陣列來建立一個DataFrame,如果我們只是傳入numpy的陣列而不指定列名的話,那麼pandas將會以數字作為索引為我們建立列:
我們在建立的時候為columns這個欄位傳入一個string的list即可為它指定列名:
從檔案讀取
pandas另外一個非常強大的功能就是可以從各種格式的檔案當中讀取資料建立DataFrame,比如像是常用的excel、csv,甚至是資料庫也可以。
對於excel、csv、json等這種結構化的資料,pandas提供了專門的api,我們找到對應的api進行使用即可:
如果是一些比較特殊格式的,也沒有關係,我們使用read_table,它可以從各種文字檔案中讀取資料,通過傳入分隔符等引數完成建立。比如在上一篇驗證PCA降維效果的文章當中,我們從.data格式的檔案當中讀取了資料。該檔案當中列和列之間的分隔符是空格,而不是csv的逗號或者是table符。我們通過傳入sep這個引數,指定分隔符就完成了資料的讀取。
這個header引數表示檔案的哪些行作為資料的列名,預設header=0,也即會將第一行作為列名。如果資料當中不存在列名,需要指定header=None,否則會產生問題。我們很少會出現需要用到多級列名的情況,所以一般情況下最常用的就是取預設值或者是令它等於None。
在所有這些建立DataFrame的方法當中最常用的就是最後一種,從檔案讀取。因為我們做機器學習或者是參加kaggle當中的一些比賽的時候,往往資料都是現成的,以檔案的形式給我們使用,需要我們自己建立資料的情況很少。如果是在實際的工作場景,雖然資料不會存在檔案當中,但是也會有一個源頭,一般是會儲存在一些大資料平臺當中,模型從這些平臺當中獲取訓練資料。
所以總體來說,我們很少使用其他建立DataFrame的方法,我們有所瞭解,著重掌握從檔案讀取的方法即可。
常用操作
下面介紹一些pandas的常用操作,這些操作是我在沒有系統學習pandas的使用方法之前就已經瞭解的。瞭解的原因也很簡單,因為它們太常用了,可以說是必知必會的常識性內容。
檢視資料
我們在jupyter當中執行執行DataFrame的例項會為我們打出DataFrame中所有的資料,如果資料行數過多,則會以省略號的形式省略中間的部分。對於資料量很大的DataFrame,我們一般不會直接這樣輸出展示,而是會選擇展示其中的前幾條或者是後幾條資料。這裡就需要用到兩個api。
展示前若干條資料的方法叫做head,它接受一個引數,允許我們制定讓它從頭開始展示我們指定條數的資料。
既然有展示前面若干條自然也有展示最後若干條的api,這樣的api叫做tail。通過它我們可以檢視DataFrame最後指定條數的資料:
列的增刪改查
前面我們曾經提到過,對於DataFrame而言,它其實相當於Series組合成的dict。既然是dict我們自然可以根據key值獲取指定的Series。
DataFrame當中有兩種方法獲取指定的列,我們可以通過.加列名的方式或者也可以通過dict查詢元素的方式來查詢:
我們也可以同時讀取多列,如果是多列的話,只支援一種方法就是通過dict查詢元素的方法。它允許接收傳入一個list,可以查找出這個list當中的列對應的資料。返回的結果是這些新的列組成的新DataFrame。
我們可以用del刪除一個我們不需要的列:
我們要建立一個新的列也很簡單,我們可以像是dict賦值一樣,直接為DataFrame賦值即可:
賦值的物件並不是只能是實數,也可以是一個數組:
我們要修改某一列也非常簡單,也是通過賦值一樣的方法覆蓋原資料即可。
轉成numpy陣列
有時候我們使用pandas不方便,想要獲取它對應的原始資料,可以直接使用.values獲取DataFrame對應的numpy陣列:
由於在DataFrame當中每一列單獨一個型別,而轉化成numpy的陣列之後所有資料共享型別。那麼pandas會為所有的列找一個通用型別,這就是為什麼經常會得到一個object型別的原因。所以在使用.values之前最好先檢視一下型別,保證一下不會因為型別而出錯。
總結
在今天的文章當中我們瞭解了DataFrame與Series的關係,也學習了一些DataFrame的基礎和常用的用法。雖然DataFrame可以近似看成是Series組合成的dict,但實際上它作為一個單獨的資料結構,也擁有許多自己的api,支援許多花式的操作,是我們處理資料強有力的工具。
有專業機構做過統計,對於一個演算法工程師而言,大約70%的時間會被投入在資料的處理上。真正編寫模型、調參的時間可能不到20%,從這當中我們可以看到資料處理的必要性和重要程度。在Python領域當中,pandas是資料處理最好用的手術刀和工具箱,希望大家都能將它掌握。
如果喜歡本文,可以的話,來一波三連,給我一點支援吧(關注、在看、點贊)。
本文使用 mdnice 排版