1.數據錯誤:
錯誤類型
– 臟數據或錯誤數據
• 比如, Age = -2003
– 數據不正確
• ‘0’ 代表真實的0,還是代表缺失
– 數據不一致
• 比如收入單位是萬元,利潤單位是元,或者一個單位是
美元,一個是人民幣
– 數據重復
2.缺失值處理:
處理原則
–缺失值少於20%
•連續變量使用均值或中位數填補
•分類變量不需要填補,單算一類即可,或者用眾數填補
–缺失值在20%-80%
•填補方法同上
•另外每個有缺失值的變量生成一個指示啞變量,參與后續的建模
–缺失值在大於80%
•每個有缺失值的變量生成一個指示啞變量,參與后續的建模,原始變量不使用。
3.離群值
3.1單變量離群值處理:
.繪圖。
在圖中找出離群的異常值,根據情況對其進行刪除或者對數據進行變換從而在數值上使其不離群或者不明顯。
學生化(標准化)
•用變量除以他們的標准誤就可得到學生化數值
建議的臨界值:
–|SR| >2 ,用於觀察值較少的數據集
–|SR| >3,用於觀察值較多的數據集
3.2多變量離群值
1.繪圖。
在圖中找出明顯的離群值
2.聚類法確定離群值(不要對原有數據進行改變)
聚類效果評判指標:(群內方差(距離)最小化,群間方差(距離)最大化;這里方差可以理解為一種距離(歐式距離的平方—歐式距離))
了解清洗后,接下來,就來學習一下Python的數據清洗吧!
現在有一份心臟病患者的數據,經過問卷調查之后,最終錄入數據如下:
- Age:年齡
- Areas:來自哪里,有A/B/C/D四個地區
- ID:患者的唯一識別編號
- Package:每天抽幾包煙,缺失的為-9,代表不抽煙
- SHabit:睡眠習慣,1-早睡早起;2-晚睡早起;3-早睡晚起;4-晚睡晚起
為了學習方便,假設這里就這些變量吧。
看完這個變量說明我不淡定了,這個數據存在很多問題啊!Age是年齡?158是什么鬼??還有6歲小孩,每天抽1包煙?ID是唯一編號嗎?為什么有3個1號、2個5號、2個9號、2個10號?
這個數據問題太多了,因此我要逐一來清洗一下,順便學一下數據清洗方面的知識。
1. 刪除重復
3個1號、2個5號、2個9號、2個10號。這是數據錄入中經常出現的問題——重復錄入了,所以首先我要把那么多占空間又沒用的重復數據剔除。
介紹兩個方法:data.duplicated() 和 data.drop_duplicates(),前者標記出哪些是重復的(true),后者直接將重復刪除。
所以drop.duplicates直接就將重復值刪除了,默認保留第一條。
以上是按照“有兩行數據,這兩行數據的所有變量值都一樣,這么這兩行就算重復數據”,但有時候我們會只根據一個變量來剔除重復,比如值根據Areas這個變量,那么A/B/C/D四個地區只會保留第一條,傳入take_last=True則保留最后一個:
A/B/C/D每個地區值保留一條數據了。
2. 異常值檢測
在第一步剔除重復值之后。得到了無重復數據的data_noDup:
第二步,我想檢測一下數據中有沒有異常值。首先可以用 describe() 進行一個描述分析,在第五天的學習中(第5天:Pandas,露兩手)已經學過如何對數據進行描述:
有兩個變量值得我們注意,一個是age,最大值158、最小值6,肯定有問題,另一個是package,最小值是-9,存在缺失。
用 data[條件] 的方式可以看一下有多少age大於100、age小於10,、package為-9的:
好了,檢測完畢,現在來處理這些異常值。
3. 替換
我要把異常的年齡替換成缺失,把package等於-9的替換成0(換成0是因為,不抽煙其實也就是抽煙數量為0,這樣還能少一些缺失值)。
替換的方式有2種,字典,或者替換關系組成的數組:
(1)data.replace([A, B], [A_R, B_R]),如果這里替換之后的值A_R和B_R是一樣的,那么[A_R,B_R]直接是A_R就可以了
(2)data.replace({A:A_R, B:B_R}),這是字典的方式。
所以,這里想要將age的6、158替換成缺失,就應該為:
data_noDup[‘Age’].replace([158, 6], np.nan)
將package的-9替換成0:
data_noDup[‘Package’].replace(-9, 0)
替換之后的數據命名為data_noDup_rep:
4. 數據映射
接下來的一些處理,是為了變量能夠更加便於分析,首先是要進行數據映射。什么是映射呢?以Areas為例,Areas取四個地區:A/B/C/D, 這四個地區在分析的時候並沒有什么意義,但A/B/C為城市,D為農村,這個很有意義,所以我要根據areas創建新變量CType:U-城市、R-農 村,映射關系如下:
方法就是寫一個映射字典,把A/B/C變成U,把D變成R:
areas_to_ctype={‘A’:’U’,’B’:’U’,’C’:’U’,’D’:’R’}
然后使用 map(映射字典) 去創建新變量CType:
data_noDup_rep[‘CType’]=data[‘Areas’].map(areas_to_ctype)
其實用替換也可以,但是替換是在原列上替換,而映射自己可以新建一個變量。
5. 數值變量類型化
接下來還要處理的變量是年齡Age,需要分成四組,
- 0:30歲以下,也就是0到30歲
- 1:30-40歲
- 2:40-50歲
- 3:50歲以上,不妨設為50-100歲
這個問題如果用映射MAP的話就麻煩了,每一個年齡都要寫一個映射。使用 cut 函數來分割,就可以自己分割成幾個組。
1)首先要設置幾個分割點:0、30、40、50、100:cutPoint=[0,30, 40, 50,80]
2)接着,用 cut(data, cutPoint) 的格式對age按照cutPoint進行划分:pd.cut(data_noDup_rep[‘Age’],cutPoint)
3)最后,將這個賦給新變量ageGroup:data_noDup_rep[‘ageGroup’] =pd.cut(data_noDup_rep[‘Age’],cutPoint)
這樣很不好看有木有?怎么把四個組分別用0、1、2、3來表示呢?
設定一個組標簽groupLabel=[0,1,2,3],指定 labels=groupLable 即可。
data_noDup_rep[‘ageGroup’] =pd.cut(data_noDup_rep[‘Age’],cutPoint, labels=groupLabel)
一個問題來了,依稀記得之前做過一個項目,樣本量有7000,年齡分組是按照分位數來分的,那再python中能否實現?
可以的,用 qcut(data, n) 就可以,按照分位數分n組,比如分2組,那么就按照中位數來分,分4組,就按照四分位數來分。對這個例子我分兩組:
data_noDup_rep[‘ageGroup’] =pd.qcut(data_noDup_rep[‘Age’],2)
6. 創建啞變量
啞變量一般用於兩種情況:一是變量值是無序並列的,比如例子中的SHabit,四個選項1、2、3、4是並列的;另一種就是多選題,也需要生成啞變量。
以本例中的SHabit(睡眠情況)為例,四個取值是並列的,沒有順序,因此我們要把這1個問題變成4個:
SHabit(睡眠習慣,1-早睡早起;2-晚睡早起;3-早睡晚起;4-晚睡晚起)
變成:
SHabit_1:是否早睡早起?(0-否,1-是)
SHabit_2:是否晚睡早起?(0-否,1-是)
SHabit_3:是否早睡晚起?(0-否,1-是)
SHabit_4:是否晚睡晚起?(0-否,1-是)
使用 get.dummies( data[‘SHabit’] ) 就可以直接搞定:
生成了四個變量。要把它合並入原數據data_noDup_rep中去,只要用 merge 就可以了(上一文剛剛介紹過數據的合並,戳復習→第6天:數據合並)
data_noDup_rep_dum =pd.merge(data_noDup_rep, pd.get_dummies(data_noDup_rep[‘SHabit’]),right_index=True, left_index=True)
(注:因為合並鍵值是索引,因此要用right_index=True和left_index=True)
一個問題:變量名1、2、3、4太丑了!
可以在get_dummies函數中加 prefix=’’ 選項為名字加一個前綴:
data_noDup_rep_dum =pd.merge(data_noDup_rep, pd.get_dummies(data_noDup_rep[‘SHabit’], prefix=’SHabit’ ), right_index=True, left_index=True)
變量比較多,所以換行顯示了。還有一種情況,如果SHabit是多選呢?每個人的睡眠習慣不止一種,像這樣:
這樣的多選題數據,在分析中肯定一點用沒有,處理的方法也是生成啞變量,如何生成?將在【第8天:數據清洗(2)文本分析】中學習,除此之外,還要學習如何進行分列處理、如何處理文本數據中的空白,如何使用正則表達式。
來源:http://www.itdadao.com/articles/c15a776467p0.html
(部分來自翟老師課程 ,部分來自數說工作室)