【轉載】使用pandas進行數據清洗

使用pandas進行數據清洗

本文轉載自:藍鯨的網站分析筆記
html

原文連接:使用python進行數據清洗python

 

目錄:git

 


 數據清洗是一項複雜且繁瑣(kubi)的工做,同時也是整個數據分析過程當中最爲重要的環節。有人說一個分析項目80%的時間都是在清洗數據,這聽起來有些匪夷所思,但在實際的工做中確實如此。數據清洗的目的有兩個,第一是經過清洗讓數據可用。第二是讓數據變的更適合進行後續的分析工做。換句話說就是有」髒」數據要洗,乾淨的數據也要洗。本篇文章將介紹幾種簡單的使用python進行數據清洗的方法。app

cleansing-big-data

開始以前仍是先在python中導入須要使用的庫文件,而後進行數據讀取,並建立名爲loandata的數據表。這裏爲了更好的展現清洗的步驟和結果,咱們使用的是lendingclub公開數據中的一小部分。函數

1
2
3
import numpy as np
import pandas as pd
loandata=pd.DataFrame(pd.read_excel('loandata.xlsx'))

原始數據表

數據清洗的目的有兩個,第一是經過清洗讓髒數據變的可用。這也是咱們首先要解決的問題。不管是線下人工填寫的手工表,仍是線上經過工具收集到的數據,又或者是CRM系統中導出的數據。不少數據源都有一些這樣或者那樣的問題,例如:數據中的重複值,異常值,空值,以及多餘的空格和大小寫錯誤的問題。下面咱們逐一進行處理。工具

數據表中的重複值

第一個要處理的問題是數據表中的重複值,pandas中有兩個函數是專門用來處理重複值的,第一個是duplicated函數。Duplicated函數用來查找並顯示數據表中的重複值。下面是使用這個函數對數據表進行重複值查找後的結果。網站

1
loandata.duplicated()

查看重複值
這裏有兩點須要說明:第一,數據表中兩個條目間全部列的內容都相等時duplicated纔會判斷爲重複值。(Duplicated也能夠單獨對某一列進行重複值判斷)。第二,duplicated支持從前向後(first),和從後向前(last)兩種重複值查找模式。默認是從前向後進行重複值的查找和判斷。換句話說就是將後出現的相同條件判斷爲重複值。在前面的表格中索引爲4的1311748和索引爲1的條目相同。默認狀況下後面的條目在重複值判斷中顯示爲True。spa

Pandas中的drop_duplicates函數用來刪除數據表中的重複值,判斷標準和邏輯與duplicated函數同樣。使用drop_duplicates函數後,python將返回一個只包含惟一值的數據表。下面是使用drop_duplicates函數後的結果。與原始數據相比減小了3行,仔細觀察能夠發現,drop_duplicates默認也是使用了first模式刪除了索引爲4的重複值,以及後面的另外兩個重複值。3d

1
loandata.drop_duplicates()

刪除重複值

數據表中的空值/缺失值

第二個要處理的問題是數據表中的空值,在python中空值被顯示爲NaN。在處理空值以前咱們先來檢查下數據表中的空值數量。對於一個小的數據表,咱們能夠人工查找,但對於較爲龐大的數據表,就須要尋找一個更爲方便快捷的方法了。首先,對關鍵字段進行空值查找。這裏咱們分別選擇了對loan_amnt字段和annual_inc字段查找空值。excel

Pandas中查找數據表中空值的函數有兩個,一個是函數isnull,若是是空值就顯示True。另外一個函數notnull正好相反,若是是空值就顯示False。如下兩個函數的使用方法以及經過isnull函數得到的空值數量。

1
loandata.isnull()
1
loandata.notnull()

經過isnull函數和value_counts函數分別得到了loan_amnt列和annual_inc列中的空值數據量。

計算特定列空值數量計算特定列空值數量1

對於空值有兩種處理的方法,第一種是使用fillna函數對空值進行填充,能夠選擇填充0值或者其餘任意值。第二種方法是使用dropna函數直接將包含空值的數據刪除。

1
loandata.fillna(0)
1
loandata.dropna()

這裏咱們選擇對空值數據進行填充,首先處理loan_amnt列中的空值。經過totalpymnt字段和total_tec_int字段值相減計算出loan_amnt列中的近似值。由於這裏除了利息之外還可能包括一些逾期費,手續費和罰息等,因此只能得到一個實際貸款金額近似值。因爲貸款金額一般是一個整數,所以咱們在代碼的最後對格式進行了轉換。

1
loandata['loan_amnt']=loandata['loan_amnt'].fillna(loandata['total_pymnt']-loandata['total_rec_int']).astype(np.int64)

計算並填充loan_amnt列空值

對於annual_inc列,在原始數據表中沒有可用的輔助列進行計算,所以咱們選擇用現有數據的均值進行填充。這裏能夠看到貸款用戶的收入均值爲50060美金。使用這個值對annual_inc中的空值進行填充。

1
loandata['annual_inc']=loandata['annual_inc'].fillna(loandata['annual_inc'].mean())

填充annual_inc列空值

數據間的空格

第三個要處理的是數據中的空格。空格會影響咱們後續會數據的統計和計算。從下面的結果中就能夠看出空格對於常規的數據統計形成的影響。

查看數據中的空格
咱們再對loan_status列進行頻率統計時,因爲空格的問題,相同的貸款狀態被重複計算。形成統計結果不可用。所以,咱們須要解決字段中存在的空格問題。

1
loandata['loan_status'].value_counts()

查看列中的空格

去除數據中的空格
Python中去除空格的方法有三種,第一種是去除數據兩邊的空格,第二種是單獨去除左邊的空格,第三種是單獨去除右邊的空格。

1
loandata['term']=loandata['term'].map(str.strip)
1
loandata['term']=loandata['term'].map(str.lstrip)
1
loandata['term']=loandata['term'].map(str.rstrip)

這裏咱們使用去除兩邊的空格來處理loan_status列中的空格。如下是具體的代碼和去除空格後的結果。

去除左右兩側的空格

從新查看loan_status列中每種貸款狀態的頻率,以前空格形成的影響已經沒有了,但這裏還有個問題,就是大小寫的問題。所以,咱們還須要對每種貸款狀態的大小寫進行統一化處理。這是咱們第四個要處理的問題。

查看去除空格後的數據

大小寫轉換

大小寫轉換的方法也有三種能夠選擇,分別爲所有轉換爲大寫,所有轉換爲小寫,和轉換爲首字母大寫。

1
loandata['term']=loandata['term'].map(str.upper)
1
loandata['term']=loandata['term'].map(str.lower)
1
loandata['term']=loandata['term'].map(str.title)

這裏咱們將全部貸款狀態轉換爲首字母大寫模式,並再次進行頻率統計。從下面的結果中能夠看出,結果以及消除了空格和大小寫字母混亂的影響。清晰的顯示了貸款的三種狀態出現的頻率。

規範大小寫後的數據

最後咱們還須要對數據表中關鍵字段的內容進行檢查,確保關鍵字段中內容的統一。主要包括數據是否所有爲字符,或數字。下面咱們對emp_length列進行檢驗,此列內容由數字和字符組成,若是隻包括字符,說明可能存在問題。下面的代碼中咱們檢查該列是否所有爲字符。答案所有爲False。

1
loandata['emp_length'].apply(lambda x: x.isalpha())

檢查字段內容
除此以外,還能檢驗該列的內容是否所有爲字母或數字。或者是否所有爲數字。

1
loandata['emp_length'].apply(lambda x: x. isalnum ())
1
loandata['emp_length'].apply(lambda x: x. isdigit ())

數據中的異常和極端值

第五個要處理的問題是數據中的異常值和極端值,發現異常值和極端值的方法是對數據進行描述性統計。使用describe函數能夠生成描述統計結果。其中咱們主要關注最大值(max)和最小值(min)狀況。

檢查異常和極端值
下面是對數據表進行描述統計的結果,其中loan_amnt的最大值和最小值分別爲100000美金和36美金,這不符合業務邏輯,所以能夠判斷爲異常值。

1
loandata.describe().astype(np.int64).T

檢查異常值和極端值

異常數據替換
對於異常值數據咱們這裏選擇使用replace函數對loan_amnt的異常值進行替換,這裏替換值選擇爲loan_amnt的均值。下面是具體的代碼和替換結果。

1
loandata.replace([100000,36],loandata['loan_amnt'].mean())

異常值替換爲均值

數據清洗的第二個目的是讓數據更加適合後續的分析工做。提早對數據進行預處理,後面的挖掘和分析工做會更加高效。這些預處理包括數據格式的處理,數據分組和對有價值信息的提取。下面咱們逐一來介紹這部分的操做過程和使用到的函數。

更改數據格式

第一步是更改和規範數據格式,所使用的函數是astype。下面是更改數據格式的代碼。對loan_amnt列中的數據,因爲貸款金額一般爲整數,所以咱們數據格式改成int64。若是是利息字段,因爲會有小數,所以一般設置爲float64。

1
loandata['loan_amnt']=loandata['loan_amnt'].astype(np.int64)

在數據格式中還要特別注意日期型的數據。日期格式的數據須要使用to_datatime函數進行處理。下面是具體的代碼和處理後的結果。

1
loandata['issue_d']=pd.to_datetime(loandata['issue_d'])

格式更改後能夠經過dtypes函數來查看,下面顯示了每一個字段的數據格式。

1
loandata.dtypes

查看更改後字段格式

數據分組

第二步是對數據進行分組處理,在數據表的open_acc字段記錄了貸款用戶的帳戶數量,這裏咱們能夠根據帳戶數量的多少對用戶進行分級,5個帳戶如下爲A級,5-10個帳戶爲B級,依次類推。下面是具體的代碼和處理結果。

1
2
3
bins = [0, 5, 10, 15, 20]
group_names = ['A', 'B', 'C', 'D']
loandata['categories'] = pd.cut(loandata['open_acc'], bins, labels=group_names)

首先設置了數據分組的依據,而後設置每組對應的名稱。最後使用cut函數對數據進行分組並將分組後的名稱添加到數據表中。

數據分組

數據分列

第四步是數據分列,這個操做和Excel中的分列功能很像,在原始數據表中grade列中包含了兩個層級的用戶等級信息,如今咱們經過數據分列將分級信息進行拆分。數據分列操做使用的是split函數,下面是具體的代碼和分列後的結果。

1
grade_split = pd.DataFrame((x.split('-') for x in loandata.grade),index=loandata.index,columns=['grade','sub_grade'])

數據分列

完成數據分列操做後,使用merge函數將數據匹配會原始數據表,這個操做相似Excel中的Vlookup函數的功能。經過匹配原始數據表中包括了分列後的等級信息。如下是具體的代碼和匹配後的結果。

1
loandata=pd.merge(loandata,grade_split,right_index=True, left_index=True)

數據分列後拼接

相關文章
相關標籤/搜索