用 Python 做資料處理必看:12 個使效率倍增的 Pandas 技巧(下)
7 – 資料框合併
當我們有收集自不同來源的資料時,合併資料框就變得至關重要。假設對於不同的房產型別,我們有不同的房屋均價資料。讓我們定義這樣一個數據框:
prop_rates = pd.DataFrame([1000, 5000, 12000], index=['Rural','Semiurban','Urban'],columns=['rates'])
prop_rates
現在可以把它與原始資料框合併:
data_merged = data.merge(right=prop_rates, how='inner',left_on='Property_Area',right_index=True, sort=False) data_merged.pivot_table(values='Credit_History',index=['Property_Area','rates'], aggfunc=len)
這張透視表驗證了合併成功。注意這裡的 ‘values’無關緊要,因為我們只是單純計數。
想了解更多請閱讀Pandas Reference (merge)
8 – 給資料框排序
Pandas可以輕鬆基於多列排序。方法如下:
data_sorted = data.sort_values(['ApplicantIncome','CoapplicantIncome'], ascending=False)
data_sorted[['ApplicantIncome','CoapplicantIncome']].head(10)
注:Pandas 的“sort”函式現在已經不推薦使用,我們用 “sort_values”函式代替。
想了解更多請閱讀Pandas Reference (sort_values)
9 – 繪圖(箱型圖&直方圖)
許多人可能沒意識到Pandas可以直接繪製箱型圖和直方圖,不必單獨呼叫matplotlib。只需要一行程式碼。舉例來說,如果我們想根據貸款狀態Loan_Status來比較申請者收入ApplicantIncome:
data.boxplot(column="ApplicantIncome",by="Loan_Status")
data.hist(column="ApplicantIncome",by="Loan_Status",bins=30)
可以看出獲得/未獲得貸款的人沒有明顯的收入差異,即收入不是決定性因素。
想了解更多請閱讀Pandas Reference (hist) | Pandas Reference (boxplot)
10 – 用Cut函式分箱
有時把數值聚集在一起更有意義。例如,如果我們要為交通狀況(路上的汽車數量)根據時間(分鐘資料)建模。具體的分鐘可能不重要,而時段如“上午”“下午”“傍晚”“夜間”“深夜”更有利於預測。如此建模更直觀,也能避免過度擬合。
這裡我們定義一個簡單的、可複用的函式,輕鬆為任意變數分箱。
#分箱:
def binning(col, cut_points, labels=None):
#Define min and max values:
minval = col.min()
maxval = col.max()
#利用最大值和最小值建立分箱點的列表
break_points = [minval] + cut_points + [maxval]
#如果沒有標籤,則使用預設標籤0 ... (n-1)
if not labels:
labels = range(len(cut_points)+1)
#使用pandas的cut功能分箱
colBin = pd.cut(col,bins=break_points,labels=labels,include_lowest=True)
return colBin
#為年齡分箱:
cut_points = [90,140,190]
labels = ["low","medium","high","very high"]
data["LoanAmount_Bin"] = binning(data["LoanAmount"], cut_points, labels)
print pd.value_counts(data["LoanAmount_Bin"], sort=False)
想了解更多請閱讀 Pandas Reference (cut)
11 – 為分類變數編碼
有時,我們會面對要改動分類變數的情況。原因可能是:
有些演算法(如羅吉斯迴歸)要求所有輸入專案是數字形式。所以分類變數常被編碼為0, 1….(n-1)
有時同一個分類變數可能會有兩種表現方式。如,溫度可能被標記為“High”, “Medium”, “Low”,“H”, “low”。這裡 “High” 和 “H”都代表同一類別。同理, “Low” 和“low”也是同一類別。但Python會把它們當作不同的類別。
一些類別的頻數非常低,把它們歸為一類是個好主意。
這裡我們定義了一個函式,以字典的方式輸入數值,用‘replace’函式進行編碼。
#使用Pandas replace函式定義新函式:
def coding(col, codeDict):
colCoded = pd.Series(col, copy=True)
for key, value in codeDict.items():
colCoded.replace(key, value, inplace=True)
return colCoded
#把貸款狀態LoanStatus編碼為Y=1, N=0:
print 'Before Coding:'
print pd.value_counts(data["Loan_Status"])
data["Loan_Status_Coded"] = coding(data["Loan_Status"], {'N':0,'Y':1})
print '\nAfter Coding:'
print pd.value_counts(data["Loan_Status_Coded"])
編碼前後計數不變,證明編碼成功。
想了解更多請閱讀 Pandas Reference (replace)
12 – 在一個數據框的各行迴圈迭代
這不是一個常見的操作。但你總不想卡在這裡吧?有時你會需要用一個for迴圈來處理每行。例如,一個常見的問題是變數處置不當。通常見於以下情況:
帶數字的分類變數被當做數值。
(由於出錯)帶文字的數值變數被當做分類變數。
所以通常來說手動定義變數型別是個好主意。如我們檢查各列的資料型別:
#檢查當前資料型別:
data.dtypes
這裡可以看到分類變數Credit_History被當作浮點數。對付這個問題的一個好辦法是建立一個包含變數名和型別的csv檔案。通過這種方法,我們可以定義一個函式來讀取檔案,併為每列指派資料型別。舉例來說,我們建立了csv檔案datatypes.csv。
#載入檔案:
colTypes = pd.read_csv('datatypes.csv')
print colTypes
載入這個檔案之後,我們能對每行迭代,把用‘type’列把資料型別指派到‘feature’ 列對應的專案。
#迭代每行,指派變數型別。
#注,astype用來指定變數型別。
for i, row in colTypes.iterrows(): #i: dataframe索引; row: 連續的每行
if row['feature']=="categorical":
data[row['feature']]=data[row['feature']].astype(np.object)
elif row['feature']=="continuous":
data[row['feature']]=data[row['feature']].astype(np.float)
print data.dtypes
現在信用記錄這一列的型別已經成了‘object’ ,這在Pandas中代表分類變數。
想了解更多請閱讀Pandas Reference (iterrows)