1. 程式人生 > >用 Python 做資料處理必看:12 個使效率倍增的 Pandas 技巧(上)

用 Python 做資料處理必看:12 個使效率倍增的 Pandas 技巧(上)

Blog Picture

導語

Python正迅速成為資料科學家偏愛的語言,這合情合理。它擁有作為一種程式語言廣闊的生態環境以及眾多優秀的科學計算庫。如果你剛開始學習Python,可以先了解一下Python的學習路線。
在眾多的科學計算庫中,我認為Pandas對資料科學運算最有用。Pandas,加上Scikit-learn幾乎能構成了資料科學家所需的全部工具。 本文旨在提供Python資料處理的12種方法。文中也分享了一些會讓你的工作更加便捷的小技巧。
在繼續推進之前,我推薦讀者閱覽一些關於資料探索 (data exploration)的程式碼。
為了幫助理解,本文用一個具體的資料集進行運算和操作。本文使用了貸款預測(loan prediction) 問題資料集,下載資料集請到
http://datahack.analyticsvidhya.com/contest/practice-problem-loan-prediction。

開始工作

首先我要匯入要用的模組,並把資料集載入Python環境。


import pandas as pd

import numpy as np

data = pd.read_csv("train.csv", index_col="Loan_ID")

1.布林索引(Boolean Indexing)

如何你想用基於某些列的條件篩選另一列的值,你會怎麼做?例如,我們想要一個全部無大學學歷但有貸款的女性列表。這裡可以使用布林索引。程式碼如下:


data.loc[(data["Gender"]=="Female") & (data["Education"]=="Not Graduate") & (data["Loan_Status"]=="Y"), ["Gender","Education","Loan_Status"]]


想了解更多請閱讀 Pandas Selecting and Indexing

2.Apply函式

Apply是擺弄資料和創造新變數時常用的一個函式。Apply把函式應用於資料框的特定行/列之後返回一些值。這裡的函式既可以是系統自帶的也可以是使用者定義的。例如,此處可以用它來尋找每行每列的缺失值個數:


#建立一個新函式:

def num_missing(x):

  return sum(x.isnull())

#Apply到每一列:

print "Missing values per column:"

print data.apply(num_missing, axis=0) #axis=0代表函式應用於每一列

#Apply到每一行:

print "\nMissing values per row:"

print data.apply(num_missing, axis=1).head() #axis=1代表函式應用於每一行

輸出結果:

由此我們得到了想要的結果。
注意:第二個輸出使用了head()函式,因為資料包含太多行。
想了解更多請閱讀 Pandas Reference (apply)

3.替換缺失值

‘fillna()’ 可以一次解決這個問題。它被用來把缺失值替換為所在列的平均值/眾數/中位數。


#首先匯入一個尋找眾數的函式:

from scipy.stats import mode

mode(data['Gender'])

輸出: ModeResult(mode=array([‘Male’], dtype=object), count=array([489]))
返回了眾數及其出現次數。記住,眾數可以是個陣列,因為高頻的值可能不只一個。我們通常預設使用第一個:


mode(data['Gender']).mode[0]


現在可以填補缺失值,並用上一步的技巧來檢驗。


#值替換:

data['Gender'].fillna(mode(data['Gender']).mode[0], inplace=True)

data['Married'].fillna(mode(data['Married']).mode[0], inplace=True)

data['Self_Employed'].fillna(mode(data['Self_Employed']).mode[0], inplace=True)

#再次檢查缺失值以確認:

print data.apply(num_missing, axis=0)


由此可見,缺失值確定被替換了。請注意這是最基本的替換方式,其他更復雜的技術,如為缺失值建模、用分組平均數(平均值/眾數/中位數)填充,會在今後的文章提到。
想了解更多請閱讀 Pandas Reference (fillna)

4.透視表

Pandas可以用來建立 Excel式的透視表。例如,“LoanAmount”這個重要的列有缺失值。我們可以用根據 ‘Gender’、‘Married’、‘Self_Employed’分組後的各組的均值來替換缺失值。每個組的 ‘LoanAmount’可以用如下方法確定:


#Determine pivot table

impute_grps = data.pivot_table(values=["LoanAmount"], index=["Gender","Married","Self_Employed"], aggfunc=np.mean)

print impute_grps


想了解更多請閱讀 Pandas Reference (Pivot Table)

5.多重索引

你可能注意到上一步驟的輸出有個奇怪的性質。每個索引都是由三個值組合而成。這叫做多重索引。它可以幫助運算快速進行。
延續上面的例子,現在我們有了每個分組的值,但還沒有替換。這個任務可以用現在學過的多個技巧共同完成。


#只在帶有缺失值的行中迭代:

for i,row in data.loc[data['LoanAmount'].isnull(),:].iterrows():

  ind = tuple([row['Gender'],row['Married'],row['Self_Employed']])

  data.loc[i,'LoanAmount'] = impute_grps.loc[ind].values[0]

#再次檢查缺失值以確認:

print data.apply(num_missing, axis=0)


注:

多重索引需要在loc中用到定義分組group的元組(tuple)。這個元組會在函式中使用。
需要使用.values[0]字尾。因為預設情況下元素返回的順序與原資料庫不匹配。在這種情況下,直接指派會返回錯誤。

6. 二維表

這個功能可被用來獲取關於資料的初始“印象”(觀察)。這裡我們可以驗證一些基本假設。例如,本例中“Credit_History” 被認為對欠款狀態有顯著影響。可以用下面這個二維表進行驗證:


pd.crosstab(data["Credit_History"],data["Loan_Status"],margins=True)


這些數字是絕對數值。不過,百分比數字更有助於快速瞭解資料。我們可以用apply函式達到目的:


def percConvert(ser):

  return ser/float(ser[-1])

  pd.crosstab(data["Credit_History"],data["Loan_Status"],margins=True).apply(percConvert, axis=1)


現在可以很明顯地看出,有信用記錄的人獲得貸款的可能性更高:有信用記錄的人有80% 獲得了貸款,沒有信用記錄的人只有 9% 獲得了貸款。
但不僅僅是這樣,其中還包含著更多資訊。由於我現在知道了有信用記錄與否非常重要,如果用信用記錄來預測是否會獲得貸款會怎樣?令人驚訝的是,在614次試驗中我們能預測正確460次,足足有75%!
如果此刻你在納悶,我們要統計模型有什麼用,我不會怪你。但相信我,在此基礎上提高0.001%的準確率都是充滿挑戰性的。你是否願意接受這個挑戰?
注:對訓練集而言是75% 。在測試集上有些不同,但結果相近。同時,我希望這個例子能讓人明白,為什麼提高0.05% 的正確率就能在Kaggle排行榜上跳升500個名次。
想了解更多請閱讀Pandas Reference (crosstab)