缺失值的識別
# 判斷各變數中是否存在缺失值
data3.isnull().any(axis = 0)
# 各變數中缺失值的數量
data3.isnull().sum(axis = 0)
# 各變數中缺失值的比例
data3.isnull().sum(axis = 0)/data3.shape[0]複製**
如上結果所示,資料集data3中有三個變數存在缺失值,即gender、age和edu,它們的缺失數量分別為136、100和1,927,缺失比例分別為4.53%、3.33%和64.23%。
需要說明的是,判斷資料是否為缺失值nan,可以使用isnull「方法」,它會返回與原資料行列數相同的矩陣,並且矩陣的元素為bool型別的值,為了得到每一列的判斷結果,仍然需要any「方法」(且設定「方法」內的axis引數為0);統計各變數的缺失值個數可以在isnull的基礎上使用sum「方法」(同樣需要設定axis引數為0);計算缺失比例就是在缺失數量的基礎上除以總的樣本量(shape方法返回資料集的行數和列數,[0]表示取出對應的資料行數)。
讀者可能對**中的「axis=0」感到困惑,它代表了什麼?為什麼是0?是否還可以寫其他值?下面通過圖表的形式來說明axis引數的用法:
假設上圖為學生的考試成績表,如果直接對成績表中的分數進行加和操作,得到的是所有學生的分數總和(很顯然沒有什麼意義),如果按學生分別計算總分,將是上圖從左到右的轉換。該轉換的特徵是列數發生了變化(可以是列數減少,也可以是列數增多),類似於在水平方向上受了外部的壓力或拉力,這樣的外力就理解為軸axis為1的效果(便於理解,可以想象為飛機在有動力的情況下,可以保持水平飛行狀態)。
同樣對於如上的學生成績表,如果直接對成績表中的分數計算平均值,得到的是所有學生的平均分數(很顯然也沒有什麼意義),如果按學科分別計算平均分,將是上圖中從上到下的轉換。該轉換的特徵是行數發生了變化(可以是行數減少,也可以是行數增多),類似於在垂直方向上受了外部的擠壓或拉伸,這樣的外力就理解為軸axis為0的效果(便於理解,可以想象為飛機在沒有動力的情況下,呈下降趨勢)。
如上是關於變數方面的缺失值判斷過程,還可以利用下方的**識別資料行的缺失值分布情況:# 判斷資料行中是否存在缺失值
如上結果所示,返回true值,說明data3中的資料行存在缺失值。**中使用了兩次any「方法」,第一次用於判斷每一行對應的true(即行內有缺失值)或false值(即行內沒有缺失值);第二次則用於綜合判斷所有資料行中是否包含缺失值。同理,進一步還可以判斷缺失行的具體數量和佔比,**如下:
# 缺失觀測的行數
data3.isnull().any(axis = 1).sum()
# 缺失觀測的比例
data3.isnull().any(axis = 1).sum()/data3.shape[0]複製**
如上結果所示,3000行的資料集中有2024行存在缺失值,缺失行的比例約67.47%。不管是變數角度的缺失值判斷,還是資料行角度的缺失值判斷,一旦發現缺失值,都需要對其作相應的處理,否則一定程度上都會影響資料分析或挖掘的準確性。
缺失值的處理辦法
通常對於缺失值的處理,最常用的方法無外乎刪除法、替換法和插補法。刪除法是指將缺失值所在的觀測行刪除(前提是缺失行的比例非常低,如5%以內),或者刪除缺失值所對應的變數(前提是該變數中包含的缺失值比例非常高,如70%左右);替換法是指直接利用缺失變數的均值、中位數或眾數替換該變數中的缺失值,其好處是缺失值的處理速度快,弊端是易產生有偏估計,導致缺失值替換的準確性下降;插補法則是利用有監督的機器學習方法(如回歸模型、樹模型、網路模型等)對缺失值作**,其優勢在於**的準確性高,缺點是需要大量的計算,導致缺失值的處理速度大打折扣。下面將選擇刪除法、替換法和插補法對缺失值進行處理,**如下:
# 刪除字段 -- 如刪除缺失率非常高的edu變數
data3.drop(labels = 'edu', axis = 1, inplace=true)
# 資料預覽
data3.head()複製**
如上結果所示,表中的edu變數已被成功刪除。對於欄位的刪除可以選擇drop「方法」,其中labels引數用於指定需要刪除的變數名稱,如果是多個變數,則需要將這些變數名稱寫在一對中括號內(如['var1','var2','var3']);刪除變數一定要設定axis引數為1,因為變數個數發生了變化(所以,借助於axis引數也可以刪除觀測行啦);inplace則表示是否原地修改,即是否直接將原表中的字段進行刪除,這裡設定為true,如果設定為false,則將刪除變數的預覽效果輸出來,而非真正改變原始資料。
# 刪除觀測,-- 如刪除age變數中所對應的缺失觀測
data3_new = data3.drop(labels = data3.index[data3['age'].isnull()],
axis = 0)
# 檢視資料的規模
data3_new.shapeout:(2900, 5)複製**
如上結果所示,利用drop「方法」實現了資料行的刪除,但必須將axis引數設定為0,而此時的labels引數則需要指定待刪除的行編號。這裡的行編號是借助於index「方法」(用於返回原始資料的行編號)和isnull「方法」(用於判斷資料是否為缺失狀態,如果是缺失則返回true)實現的,其邏輯就是將true對應的行編號取出來,傳遞給labels引數。
如果變數的缺失比例非常大,或者缺失行的比例非常小時,使用刪除法是乙個不錯的選擇,反之,將會丟失大量的資料資訊而得不償失。接下來講解如何使用替換法處理缺失值,**如下:
# 替換法處理缺失值
data3.fillna(value = , inplace = true # 原地修改資料 )
# 再次檢視各變數的缺失比例
data3.isnull().sum(axis = 0)複製**
如上結果所示,採用替換法後,原始資料中的變數不再含有缺失值。缺失值的填充使用的是fillna「方法」,其中value引數可以通過字典的形式對不同的變數指定不同的值。需要強調的是,如果計算某個變數的眾數,一定要使用索引技術,例如**中的[0],表示取出眾數序列中的第乙個(我們知道,眾數是指出現頻次最高的值,假設乙個變數中有多個值共享最高頻次,那麼python將會把這些值以序列的形式儲存起來,故取出指定的眾數值,必須使用索引)。
正如前文所說,雖然替換法思想簡單、效率高效,但是其替換的值往往不具有很高的準確性,於是出現了插補方法。該方法需要使用機器學習演算法,不妨以knn演算法為例,對titanic資料集中的age變數做插補法完成缺失值的處理。**如下:
# 讀取資料
titanic = pd.read_csv('titanic.csv')
# 刪除缺失嚴重的cabin變數
titanic.drop(labels='cabin', axis = 1,
inplace=true)
# 根據embarked變數,刪除對應的缺失行
titanic.dropna(subset=['embarked'], inplace=true)
# 刪除無關緊要的變數(這些變數對後面**年齡沒有太多的幫助)
titanic.drop(labels=['passengerid','name','ticket','embarked'], axis = 1, inplace=true)
# 將字元型的性別變數對映為數值變數
titanic.*** = titanic.***.map()
# 將資料拆分為兩組,一是年齡缺失組,二是年齡非缺失組,後續基於非缺失值構建knn模型,再對缺失組做**
nomissing = titanic.loc[~titanic.age.isnull(),]missing = titanic.loc[titanic.age.isnull(),]
# 匯入機器學習的第三方包
from sklearn import neighbors
# 提取出所有的自變數
x = nomissing.columns[nomissing.columns != 'age']
# 構建模型
knn = neighbors.kneighborsregressor()
# 模型擬合
knn.fit(nomissing[x], nomissing.age)
# 年齡**
pred_age = knn.predict(missing[x])複製**
python資料清洗
對於資料中缺失的值,可以有3種方法處理 1.刪除。比如餐廳的營業額,有幾天去裝修了,確實沒營業,可以刪除 2.不處理 有一些模型可以將缺失值作為一種特殊的值,可以直接建模。3.補上 均值 中位數 眾數 一般情況吧 固定值 比如工資啊,補貼啊 最近臨插補 最近的值,相鄰的,補上 下面是拉格朗日插值法 ...
資料清洗 python
資料清洗 python 1.1引言 對於處理大資料問題,首先就是要進行資料預處理,排除掉那些那些很離譜的資料,當然我們肯定不能乙個乙個用眼睛來找 容易累死 所以我們就要學會如何用程式來進行資料的預處理,我們常常用兩種語言 matlab和python,這裡我先介紹一下用python進行資料清洗。1.2...
Python 資料清洗
重複值處理 一般採取刪除法,但是有些不能刪 df.duplicated df.duplicated subset keep last first np.sum sd.duplicated df.dorp duplicates subset keep last first inplace true f...