利用Python進行數(shù)據(jù)清洗的操作指南
你一定聽說過這句著名的數(shù)據(jù)科學名言:
在數(shù)據(jù)科學項目中, 80% 的時間是在做數(shù)據(jù)處理。
如果你沒有聽過,那么請記住:數(shù)據(jù)清洗是數(shù)據(jù)科學工作流程的基礎。 機器學習模型會根據(jù)你提供的數(shù)據(jù)執(zhí)行,混亂的數(shù)據(jù)會導致性能下降甚至錯誤的結(jié)果,而干凈的數(shù)據(jù)是良好模型性能的先決條件。 當然干凈的數(shù)據(jù)并不意味著一直都有好的性能,模型的正確選擇(剩余 20%)也很重要,但是沒有干凈的數(shù)據(jù),即使是再強大的模型也無法達到預期的水平。
在本文中將列出數(shù)據(jù)清洗中需要解決的問題并展示可能的解決方案,通過本文可以了解如何逐步進行數(shù)據(jù)清洗。
缺失值
當數(shù)據(jù)集中包含缺失數(shù)據(jù)時,在填充之前可以先進行一些數(shù)據(jù)的分析。 因為空單元格本身的位置可以告訴我們一些有用的信息。 例如:
- NA值僅在數(shù)據(jù)集的尾部或中間出現(xiàn)。 這意味著在數(shù)據(jù)收集過程中可能存在技術(shù)問題。 可能需要分析該特定樣本序列的數(shù)據(jù)收集過程,并嘗試找出問題的根源。
- 如果列NA數(shù)量超過 70–80%,可以刪除該列。
- 如果 NA 值在表單中作為可選問題的列中,則該列可以被額外的編碼為用戶回答(1)或未回答(0)。
missingno這個python庫就可以用于檢查上述情況,并且使用起來非常的簡單,例如下圖中的白線是 NA:
import missingno as msno msno.matrix(df)
對于缺失值的填補計算有很多方法,例如:
- 平均,中位數(shù),眾數(shù)
- kNN
- 零或常數(shù)等
不同的方法相互之間有優(yōu)勢和不足,并且沒有適用于所有情況的“最佳”技術(shù)。具體可以參考我們以前發(fā)布的文章
異常值
異常值是相對于數(shù)據(jù)集的其他點而言非常大或非常小的值。 它們的存在極大地影響了數(shù)學模型的性能。 讓我們看一下這個簡單的示例:
在左圖中沒有異常值,我們的線性模型非常適合數(shù)據(jù)點。 在右圖中有一個異常值,當模型試圖覆蓋數(shù)據(jù)集的所有點時,這個異常值的存在會改變模型的擬合方式,并且使我們的模型不適合至少一半的點。
對于異常值來說我們有必要介紹一下如何確定異常,這就要從數(shù)學角度明確什么是極大或極小。
大于Q3+1.5 x IQR或小于Q1-1.5 x IQR都可以作為異常值。 IQR(四分位距) 是 Q3 和 Q1 之間的差 (IQR = Q3-Q1)。
可以使用下面函數(shù)來檢查數(shù)據(jù)集中異常值的數(shù)量:
def number_of_outliers(df): df = df.select_dtypes(exclude = 'object') Q1 = df.quantile(0.25) Q3 = df.quantile(0.75) IQR = Q3 - Q1 return ((df < (Q1 - 1.5 * IQR)) | (df > (Q3 + 1.5 * IQR))).sum()
處理異常值的一種方法是可以讓它們等于 Q3 或 Q1。 下面的lower_upper_range 函數(shù)使用 pandas 和 numpy 庫查找其外部為異常值的范圍, 然后使用clip 函數(shù)將值裁剪到指定的范圍。
def lower_upper_range(datacolumn): sorted(datacolumn) Q1,Q3 = np.percentile(datacolumn , [25,75]) IQR = Q3 - Q1 lower_range = Q1 - (1.5 * IQR) upper_range = Q3 + (1.5 * IQR) return lower_range,upper_range for col in columns: lowerbound,upperbound = lower_upper_range(df[col]) df[col]=np.clip(df[col],a_min=lowerbound,a_max=upperbound)
數(shù)據(jù)不一致
異常值問題是關(guān)于數(shù)字特征的,現(xiàn)在讓我們看看字符類型(分類)特征。 數(shù)據(jù)不一致意味著列的唯一類具有不同的表示形式。 例如在性別欄中,既有m/f,又有male/female。在這種情況下,就會有4個類,但實際上有兩類。
這種問題目前沒有自動處理的辦法,所以需要手動進行分析。 pandas 的unique函數(shù)就是為了這個分析準備的,下面看一個汽車品牌的例子:
df['CarName'] = df['CarName'].str.split().str[0] print(df['CarName'].unique())
maxda-mazda, Nissan-nissan, porcshce-porsche, toyouta-toyota等都可以進行合并。
df.loc[df['CarName'] == 'maxda', 'CarName'] = 'mazda' df.loc[df['CarName'] == 'Nissan', 'CarName'] = 'nissan' df.loc[df['CarName'] == 'porcshce', 'CarName'] = 'porsche' df.loc[df['CarName'] == 'toyouta', 'CarName'] = 'toyota' df.loc[df['CarName'] == 'vokswagen', 'CarName'] = 'volkswagen' df.loc[df['CarName'] == 'vw', 'CarName'] = 'volkswagen'
無效數(shù)據(jù)
無效的數(shù)據(jù)表示在邏輯上根本不正確的值。 例如,
- 某人的年齡是 560;
- 某個操作花費了 -8 小時;
- 一個人的身高是1200 cm等;
對于數(shù)值列,pandas的 describe 函數(shù)可用于識別此類錯誤:
df.describe()
無效數(shù)據(jù)的產(chǎn)生原因可能有兩種:
1、數(shù)據(jù)收集錯誤:例如在輸入時沒有進行范圍的判斷,在輸入身高時錯誤的輸入了1799cm 而不是 179cm,但是程序沒有對數(shù)據(jù)的范圍進行判斷。
2、數(shù)據(jù)操作錯誤
數(shù)據(jù)集的某些列可能通過了一些函數(shù)的處理。 例如,一個函數(shù)根據(jù)生日計算年齡,但是這個函數(shù)出現(xiàn)了BUG導致輸出不正確。
以上兩種隨機錯誤都可以被視為空值并與其他 NA 一起估算。
重復數(shù)據(jù)
當數(shù)據(jù)集中有相同的行時就會產(chǎn)生重復數(shù)據(jù)問題。 這可能是由于數(shù)據(jù)組合錯誤(來自多個來源的同一行),或者重復的操作(用戶可能會提交他或她的答案兩次)等引起的。 處理該問題的理想方法是刪除復制行。
可以使用 pandas duplicated 函數(shù)查看重復的數(shù)據(jù):
df.loc[df.duplicated()]
在識別出重復的數(shù)據(jù)后可以使用pandas 的 drop_duplicate 函數(shù)將其刪除:
df.drop_duplicates()
數(shù)據(jù)泄漏問題
在構(gòu)建模型之前,數(shù)據(jù)集被分成訓練集和測試集。 測試集是看不見的數(shù)據(jù)用于評估模型性能。 如果在數(shù)據(jù)清洗或數(shù)據(jù)預處理步驟中模型以某種方式“看到”了測試集,這個就被稱做數(shù)據(jù)泄漏(data leakage)。 所以應該在清洗和預處理步驟之前拆分數(shù)據(jù):
以選擇缺失值插補為例。數(shù)值列中有 NA,采用均值法估算。在 split 前完成時,使用整個數(shù)據(jù)集的均值,但如果在 split 后完成,則使用分別訓練和測試的均值。
第一種情況的問題是,測試集中的推算值將與訓練集相關(guān),因為平均值是整個數(shù)據(jù)集的。所以當模型用訓練集構(gòu)建時,它也會“看到”測試集。但是我們拆分的目標是保持測試集完全獨立,并像使用新數(shù)據(jù)一樣使用它來進行性能評估。所以在操作之前必須拆分數(shù)據(jù)集。
雖然訓練集和測試集分別處理效率不高(因為相同的操作需要進行2次),但它可能是正確的。因為數(shù)據(jù)泄露問題非常重要,為了解決代碼重復編寫的問題,可以使用sklearn 庫的pipeline。簡單地說,pipeline就是將數(shù)據(jù)作為輸入發(fā)送到的所有操作步驟的組合,這樣我們只要設定好操作,無論是訓練集還是測試集,都可以使用相同的步驟進行處理,減少的代碼開發(fā)的同時還可以減少出錯的概率。
到此這篇關(guān)于利用Python進行數(shù)據(jù)清洗的操作指南的文章就介紹到這了,更多相關(guān)Python數(shù)據(jù)清洗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 使用python數(shù)據(jù)清洗代碼實例
- 用Python進行數(shù)據(jù)清洗以及值處理
- Python常用的數(shù)據(jù)清洗方法詳解
- 一文帶你深入了解Python中的數(shù)據(jù)清洗
- 三個Python常用的數(shù)據(jù)清洗處理方式總結(jié)
- Python?數(shù)據(jù)清洗刪除缺失值替換缺失值詳情
- python?文件讀寫和數(shù)據(jù)清洗
- Python實現(xiàn)數(shù)據(jù)清洗的示例詳解
- 詳解Python中的數(shù)據(jù)清洗工具flashtext
- Python?八個數(shù)據(jù)清洗實例代碼詳解
- 如何使用Python數(shù)據(jù)清洗庫
相關(guān)文章
Python設計模式中單例模式的實現(xiàn)及在Tornado中的應用
這篇文章主要介紹了Python設計模式中單例模式的實現(xiàn)及在Tornado中的應用,講解了單例模式用于設計Tornado框架中的線程控制方面的相關(guān)問題,需要的朋友可以參考下2016-03-03Python實現(xiàn)將元組中的元素作為參數(shù)傳入函數(shù)的操作
這篇文章主要介紹了Python實現(xiàn)將元組中的元素作為參數(shù)傳入函數(shù)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06運用Python快速的對MySQL數(shù)據(jù)庫進行重命名
本文介紹了如何運用Python快速的對現(xiàn)有的數(shù)據(jù)庫進行重命名,有此需求的朋友可以參考下2021-06-06Python使用pyinstaller實現(xiàn)學生管理系統(tǒng)流程
pyinstaller是一個非常簡單的打包python的py文件的庫,下面這篇文章主要給大家介紹了關(guān)于Python?Pyinstaller庫安裝步驟以及使用方法的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-02-02