99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀用Python進行數(shù)據(jù)清洗,這7種方法你一定要掌握
用Python進行數(shù)據(jù)清洗,這7種方法你一定要掌握
2019-11-20
收藏
用Python進行<a href='/map/shujuqingxi/' style='color:#000;font-size:inherit;'>數(shù)據(jù)清洗</a>,這7種方法你一定要掌握


作者 | 常國珍、趙仁乾、張秋劍

來源 |《Python數(shù)據(jù)科學:技術詳解與商業(yè)實踐》

數(shù)據(jù)清洗是數(shù)據(jù)分析的必備環(huán)節(jié),在進行分析過程中,會有很多不符合分析要求的數(shù)據(jù),例如重復、錯誤、缺失、異常類數(shù)據(jù)。

01 重復值處理

數(shù)據(jù)錄入過程、數(shù)據(jù)整合過程都可能會產(chǎn)生重復數(shù)據(jù),直接刪除是重復數(shù)據(jù)處理的主要方法。pandas提供查看、處理重復數(shù)據(jù)的方法duplicated和drop_duplicates。以如下數(shù)據(jù)為例:

>sample = pd.DataFrame({'id':[1,1,1,3,4,5],
 'name':['Bob','Bob','Mark','Miki','Sully','Rose'],
 'score':[99,99,87,77,77,np.nan],
 'group':[1,1,1,2,1,2],})
>sample
group id name score
0 1 1 Bob 99.0
1 1 1 Bob 99.0
2 1 1 Mark 87.0
3 2 3 Miki 77.0
4 1 4 Sully 77.0
5 2 5 Rose NaN

發(fā)現(xiàn)重復數(shù)據(jù)通過duplicated方法完成,如下所示,可以通過該方法查看重復的數(shù)據(jù)。

>sample[sample.duplicated()]
group id name score
1 1 1 Bob 99.0

需要去重時,可drop_duplicates方法完成:

>sample.drop_duplicates()
group id name score
0 1 1 Bob 99.0
2 1 1 Mark 87.0
3 2 3 Miki 77.0
4 1 4 Sully 77.0
5 2 5 Rose NaN

drop_duplicates方法還可以按照某列去重,例如去除id列重復的所有記錄:

>sample.drop_duplicates('id')
group id name score
0 1 1 Bob 99.0
3 2 3 Miki 77.0
4 1 4 Sully 77.0
5 2 5 Rose NaN
用Python進行<a href='/map/shujuqingxi/' style='color:#000;font-size:inherit;'>數(shù)據(jù)清洗</a>,這7種方法你一定要掌握


02 缺失值處理

缺失值是數(shù)據(jù)清洗中比較常見的問題,缺失值一般由NA表示,在處理缺失值時要遵循一定的原則。

首先,需要根據(jù)業(yè)務理解處理缺失值,弄清楚缺失值產(chǎn)生的原因是故意缺失還是隨機缺失,再通過一些業(yè)務經(jīng)驗進行填補。一般來說當缺失值少于20%時,連續(xù)變量可以使用均值或中位數(shù)填補;分類變量不需要填補,單算一類即可,或者也可以用眾數(shù)填補分類變量。

當缺失值處于20%-80%之間時,填補方法同上。另外每個有缺失值的變量可以生成一個指示啞變量,參與后續(xù)的建模。當缺失值多于80%時,每個有缺失值的變量生成一個指示啞變量,參與后續(xù)的建模,不使用原始變量。

在下圖中展示了中位數(shù)填補缺失值和缺失值指示變量的生成過程。

用Python進行<a href='/map/shujuqingxi/' style='color:#000;font-size:inherit;'>數(shù)據(jù)清洗</a>,這7種方法你一定要掌握

▲圖5-8:缺失值填補示例

Pandas提供了fillna方法用于替換缺失值數(shù)據(jù),其功能類似于之前的replace方法,例如對于如下數(shù)據(jù):

> sample
 group id name score
0 1.0 1.0 Bob 99.0
1 1.0 1.0 Bob NaN
2 NaN 1.0 Mark 87.0
3 2.0 3.0 Miki 77.0
4 1.0 4.0 Sully 77.0
5 NaN NaN NaN NaN

分步驟進行缺失值的查看和填補如下:

1. 查看缺失情況

在進行數(shù)據(jù)分析前,一般需要了解數(shù)據(jù)的缺失情況,在Python中可以構造一個lambda函數(shù)來查看缺失值,該lambda函數(shù)中,sum(col.isnull())表示當前列有多少缺失,col.size表示當前列總共多少行數(shù)據(jù):

>sample.apply(lambda col:sum(col.isnull())/col.size)
group 0.333333
id 0.166667
name 0.166667
score 0.333333
dtype: float64

2. 以指定值填補

pandas數(shù)據(jù)框提供了fillna方法完成對缺失值的填補,例如對sample表的列score填補缺失值,填補方法為均值:

>sample.score.fillna(sample.score.mean())
0 99.0
1 85.0
2 87.0
3 77.0
4 77.0
5 85.0
Name: score, dtype: float64

當然還可以以分位數(shù)等方法進行填補:

>sample.score.fillna(sample.score.median())
0 99.0
1 82.0
2 87.0
3 77.0
4 77.0
5 82.0
Name: score, dtype: float64

3. 缺失值指示變量

pandas數(shù)據(jù)框對象可以直接調用方法isnull產(chǎn)生缺失值指示變量,例如產(chǎn)生score變量的缺失值指示變量:

>sample.score.isnull()
0 False
1 True
2 False
3 False
4 False
5 True
Name: score, dtype: bool

若想轉換為數(shù)值0,1型指示變量,可以使用apply方法,int表示將該列替換為int類型。

>sample.score.isnull().apply(int)
0 0
1 1
2 0
3 0
4 0
5 1
Name: score, dtype: int64
用Python進行<a href='/map/shujuqingxi/' style='color:#000;font-size:inherit;'>數(shù)據(jù)清洗</a>,這7種方法你一定要掌握


03 噪聲值處理

噪聲值指數(shù)據(jù)中有一個或幾個數(shù)值與其他數(shù)值相比差異較大,又稱為異常值、離群值(outlier)。

對于大部分的模型而言,噪聲值會嚴重干擾模型的結果,并且使結論不真實或偏頗,如圖5-9。需要在數(shù)據(jù)預處理的時候清除所以噪聲值。噪聲值的處理方法很多,對于單變量,常見的方法有蓋帽法、分箱法;多變量的處理方法為聚類法。下面進行詳細介紹:

用Python進行<a href='/map/shujuqingxi/' style='color:#000;font-size:inherit;'>數(shù)據(jù)清洗</a>,這7種方法你一定要掌握

▲圖5-9:噪聲值(異常值、離群值)示例:年齡數(shù)據(jù),圓圈為噪聲值

1. 蓋帽法

蓋帽法將某連續(xù)變量均值上下三倍標準差范圍外的記錄替換為均值上下三倍標準差值,即蓋帽處理(圖5-10)。

用Python進行<a href='/map/shujuqingxi/' style='color:#000;font-size:inherit;'>數(shù)據(jù)清洗</a>,這7種方法你一定要掌握

▲圖5-10:蓋帽法處理噪聲值示例

Python中可自定義函數(shù)完成蓋帽法。如下所示,參數(shù)x表示一個pd.Series列,quantile指蓋帽的范圍區(qū)間,默認凡小于百分之1分位數(shù)和大于百分之99分位數(shù)的值將會被百分之1分位數(shù)和百分之99分位數(shù)替代:

>def cap(x,quantile=[0.01,0.99]):
 """蓋帽法處理異常值
 Args:
 x:pd.Series列,連續(xù)變量
 quantile:指定蓋帽法的上下分位數(shù)范圍
 """

# 生成分位數(shù)
 Q01,Q99=x.quantile(quantile).values.tolist()

# 替換異常值為指定的分位數(shù)
 if Q01 > x.min():
 x = x.copy()
 x.loc[x<Q01] = Q01

 if Q99 < x.max():
 x = x.copy()
 x.loc[x>Q99] = Q99

 return(x)

現(xiàn)生成一組服從正態(tài)分布的隨機數(shù),sample.hist表示產(chǎn)生直方圖,更多繪圖方法會在下一章節(jié)進行講解:

>sample = pd.DataFrame({'normal':np.random.randn(1000)})
>sample.hist(bins=50)
用Python進行<a href='/map/shujuqingxi/' style='color:#000;font-size:inherit;'>數(shù)據(jù)清洗</a>,這7種方法你一定要掌握

▲圖5-11:未處理噪聲時的變量直方圖

pandas數(shù)據(jù)框所有列進行蓋帽法轉換,可以以如下寫法,從直方圖對比可以看出蓋帽后極端值頻數(shù)的變化。

>new = sample.apply(cap,quantile=[0.01,0.99])
>new.hist(bins=50)
用Python進行<a href='/map/shujuqingxi/' style='color:#000;font-size:inherit;'>數(shù)據(jù)清洗</a>,這7種方法你一定要掌握

▲圖5-12:處理完噪聲后的變量直方圖

2. 分箱法

分箱法通過考察數(shù)據(jù)的“近鄰”來光滑有序數(shù)據(jù)的值。有序值分布到一些桶或箱中。

分箱法包括等深分箱:每個分箱中的樣本量一致;等寬分箱:每個分箱中的取值范圍一致。直方圖其實首先對數(shù)據(jù)進行了等寬分箱,再計算頻數(shù)畫圖。

比如價格排序后數(shù)據(jù)為:4、8、15、21、21、24、25、28、34

將其劃分為(等深)箱:

  • 箱1:4、8、15
  • 箱2:21、21、24
  • 箱3:25、28、34

將其劃分為(等寬)箱:

  • 箱1:4、8
  • 箱2:15、21、21、24
  • 箱3:25、28、34

分箱法將異常數(shù)據(jù)包含在了箱子中,在進行建模的時候,不直接進行到模型中,因而可以達到處理異常值的目的。

pandas的qcut函數(shù)提供了分箱的實現(xiàn)方法,下面介紹如何具體實現(xiàn)。

等寬分箱:qcut函數(shù)可以直接進行等寬分箱,此時需要的待分箱的列和分箱個數(shù)兩個參數(shù),如下所示,sample數(shù)據(jù)的int列為從10個服從標準正態(tài)分布的隨機數(shù):

>sample =pd.DataFrame({'normal':np.random.randn(10)})
>sample
normal
0 0.065108
1 -0.597031
2 0.635432
3 -0.491930
4 -1.894007
5 1.623684
6 1.723711
7 -0.225949
8 -0.213685
9 -0.309789

現(xiàn)分為5箱,可以看到,結果是按照寬度分為5份,下限中,cut函數(shù)自動選擇小于列最小值一個數(shù)值作為下限,最大值為上限,等分為五分。結果產(chǎn)生一個Categories類的列,類似于R中的factor,表示分類變量列。

此外弱數(shù)據(jù)存在缺失,缺失值將在分箱后將繼續(xù)保持缺失,如下所示:

>pd.cut(sample.normal,5)
 0 (-0.447, 0.277]
 1 (-1.17, -0.447]
 2 (0.277, 1.0]
 3 (-1.17, -0.447]
 4 (-1.898, -1.17]
 5 (1.0, 1.724]
 6 (1.0, 1.724]
 7 (-0.447, 0.277]
 8 (-0.447, 0.277]
 9 (-0.447, 0.277]
Name: normal, dtype: category
Categories (5, interval[float64]): [(-1.898, -1.17] < (-1.17, -0.447] < (-0.447, 0.277] < (0.277, 1.0] < (1.0, 1.724]]

這里也可以使用labels參數(shù)指定分箱后各個水平的標簽,如下所示,此時相應區(qū)間值被標簽值替代:

> pd.cut(sample.normal,bins=5,labels=[1,2,3,4,5])
0 1
1 1
2 2
3 2
4 3
5 3
6 4
7 4
8 5
9 5
Name: normal, dtype: category
Categories (5, int64): [1 < 2 < 3 < 4 < 5]
用Python進行<a href='/map/shujuqingxi/' style='color:#000;font-size:inherit;'>數(shù)據(jù)清洗</a>,這7種方法你一定要掌握


標簽除了可以設定為數(shù)值,也可以設定為字符,如下所示,將數(shù)據(jù)等寬分為兩箱,標簽為‘bad’,‘good’:

>pd.cut(sample.normal,bins=2,labels=['bad','good'])
0 bad
1 bad
2 bad
3 bad
4 bad
5 good
6 good
7 good
8 good
9 good
Name: normal, dtype: category
Categories (2, object): [bad < good]

等深分箱:等深分箱中,各個箱的寬度可能不一,但頻數(shù)是幾乎相等的,所以可以采用數(shù)據(jù)的分位數(shù)來進行分箱。依舊以之前的sample數(shù)據(jù)為例,現(xiàn)進行等深度分2箱,首先找到2箱的分位數(shù):

>sample.normal.quantile([0,0.5,1])
0.0 0.0
0.5 4.5
1.0 9.0
Name: normal, dtype: float64

在bins參數(shù)中設定分位數(shù)區(qū)間,如下所示完成分箱,include_lowest=True參數(shù)表示包含邊界最小值包含數(shù)據(jù)的最小值:

>pd.cut(sample.normal,bins=sample.normal.quantile([0,0.5,1]),
 include_lowest=True)
0 [0, 4.5]
1 [0, 4.5]
2 [0, 4.5]
3 [0, 4.5]
4 [0, 4.5]
5 (4.5, 9]
6 (4.5, 9]
7 (4.5, 9]
8 (4.5, 9]
9 (4.5, 9]
Name: normal, dtype: category
Categories (2, object): [[0, 4.5] < (4.5, 9)]

此外也可以加入label參數(shù)指定標簽,如下所示:

>pd.cut(sample.normal,bins=sample.normal.quantile([0,0.5,1]),
 include_lowest=True)
0 bad
1 bad
2 bad
3 bad
4 bad
5 good
6 good
7 good
8 good
9 good
Name: normal, dtype: category
Categories (2, object): [bad < good]

3. 多變量異常值處理-聚類法

通過快速聚類法將數(shù)據(jù)對象分組成為多個簇,在同一個簇中的對象具有較高的相似度,而不同的簇之間的對象差別較大。聚類分析可以挖掘孤立點以發(fā)現(xiàn)噪聲數(shù)據(jù),因為噪聲本身就是孤立點。

本案例考慮兩個變量income和age,散點圖如圖5-13所示,其中A、B表示異常值:

用Python進行<a href='/map/shujuqingxi/' style='color:#000;font-size:inherit;'>數(shù)據(jù)清洗</a>,這7種方法你一定要掌握

▲圖5-13:多變量異常值示例

對于聚類方法處理異常值,其步驟如下所示:

輸入:數(shù)據(jù)集S(包括N條記錄,屬性集D:{年齡、收入}),一條記錄為一個數(shù)據(jù)點,一條記錄上的每個屬性上的值為一個數(shù)據(jù)單元格。數(shù)據(jù)集S有N×D個數(shù)據(jù)單元格,其中某些數(shù)據(jù)單元格是噪聲數(shù)據(jù)。

輸出:孤立數(shù)據(jù)點如圖所示。孤立點A是我們認為它是噪聲數(shù)據(jù),很明顯它的噪聲屬性是收入,通過對收入變量使用蓋帽法可以剔除A。

另外,數(shù)據(jù)點B也是一個噪聲數(shù)據(jù),但是很難判定它在哪個屬性上的數(shù)據(jù)出現(xiàn)錯誤。這種情況下只可以使用多變量方法進行處理。

常用檢查異常值聚類算法為K-means聚類,會在后續(xù)章節(jié)中詳細介紹,本節(jié)不贅述。

數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師考試動態(tài)
數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調,回調的第一個參數(shù)驗證碼對象,之后可以使用它調用相應的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }