Pandas 缺失值的處理
1. 前言
通過前面幾個小節的學習,我們掌握了 Pandas 解析數據和數據增刪改查的基礎操作,能有效對數據的量和內容進行處理,但我們在解析數據的時候經常會出現缺失值的情況,這些缺失數據的存在不僅影響數據的美觀,還會影響到數據分析和挖掘的結果,那 Pandas 庫中又是怎么解決缺失值這一問題的呢?
針對數據中的缺失值,Pandas 庫提供了便捷的操作去檢查缺失值,并對缺失值作出處理,本小節,我們將學習 Pandas 檢測缺失值的方法,以及 Pandas 處理缺失值常見的兩種方式。
2. 缺失值的檢測
在學習進行缺失值處理之前,我們先來看一下什么是缺失值,為什么會出現缺失值?
缺失值 —— 是指粗糙數據中由于缺少信息而造成的數據的聚類、分組、刪失或截斷。它指的是現有數據集中某個或某些屬性的值是不完全的。(來源:百度百科)
缺失值的出現是很正常的一種現象,首先我們要正視缺失值的存在,缺失值的出現一般來說有機械原因和人為原因,但在我們實際應用中,多說是我們人為的失誤或錯誤的操作導致的缺失,缺失值的出現對于我們分析數據的過程不會產生過大的影響,但是對于數據分析的結果可能會產生致命的影響,影響數據的準確性和結果的可靠性。
在 Pandas 中,對于缺失值使用浮點值 NaN 進行表示,如下圖我們將 Excel 數據文件中刪除幾個數據值,進行數據的解析:
然后我通過 Pandas 庫進行數據的解析,可以看到數據缺失值的表示 NaN:
2.1 isnull () 函數
該函數用來檢測缺失值,如果是缺失值 NaN 則數據返回的是 True,不是缺失值返回的是 False。
# 導入pandas包
import pandas as pd
data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第11小節/execl數據demo.xlsx"
# 解析數據
data = pd.read_excel(data_path)
print(data)
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 java NaN 45.6 James Gosling
1 python 1991年 67.0 NaN
2 NaN 1972年 NaN Dennis MacAlistair Ritchie
3 js NaN NaN Brendan Eich
4 php 2012年 NaN Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
# 檢查是否是缺失值
data.isnull()
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 False True False False
1 False False False True
2 True False True False
3 False True True False
4 False False True False
5 False False False False
輸出解析:通過結果可以看到,是缺失值 NaN 的數據,在該函數檢查后,都返回了 True,否則則是 False。
2.2 notnull () 函數
該函數也能檢測缺失值,但是和 isnull () 函數相反,對于缺失值 NaN 的數據返回 False,否則為 True。
# data 是上面從 Excel 中解析出來的數據
# 檢查是否不是缺失值
data.notnull()
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 True False True True
1 True True True False
2 False True False True
3 True False False True
4 True True False True
5 True True True True
輸出解析:通過結果可以看到,不是缺失值 NaN 的數據,在該函數檢查后,都返回了 True,否則則是 False。
3. 缺失值的處理
Pandas 提供了便捷的方法去檢測缺失值,當然他還提供了對應的函數去處理缺失值,這里我們將學習缺失值的兩種處理方式,一種是過濾缺失值,也就對存在缺失值的行或者列,進行過濾操作;另一種是我們對缺失的數據進行填充處理。
3.1 dropna () 函數
該函數用于過濾含有缺失值的數據行或者列,操作之后會返回一個新的數據集,該函數提供了豐富的參數設置,下面列舉了該函數常用的幾個參數:
參數名 | 說明 |
---|---|
axis | 指定是行還是列的過濾( 0 指行,1 為列),默認 axis=0 |
how | 指定缺失值過濾的依據,含有缺失值就過濾(how=“any” 默認)還是全是全是缺失值才過濾(how=“all”) |
thresh | 指保留至少含有多少個非缺失值的行或列(參數值為整數) |
subset | 指定特定的行或者列進行缺失值過濾 |
下面我們將通過實際程序操作,學習每個參數的使用方式:
# 導入pandas包
import pandas as pd
data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第11小節/execl數據demo.xlsx"
# 解析數據
data = pd.read_excel(data_path)
print(data)
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 java NaN 45.6 James Gosling
1 python 1991年 67.0 NaN
2 NaN 1972年 NaN Dennis MacAlistair Ritchie
3 js NaN NaN Brendan Eich
4 php 2012年 NaN Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
###### dropna 過濾缺失值
# 1. axis=0 設置過濾行中有缺失值的數據
new_data= data.dropna(axis=0)
print(new_data)
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
5 C++ 1983年 75.0 Bjarne Stroustrup
# 結果解析:可以看到所有含 NaN 的數據行都被過濾掉,只剩下一行數據
# 2. axis=1 設置過濾行列中缺失值的數據
new_data= data.dropna(axis=1)
print(new_data)
# --- 輸出結果 ---
Empty DataFrame
Columns: []
Index: [0, 1, 2, 3, 4, 5]
# 結果解析:因為原數據中每一列都有 NaN 數據的存在,所以 axis=1 操作后,數據集為 Empty DataFrame
# 3. how="all" 設置所有值都為 NaN 的數據列才被過濾
new_data= data.dropna(axis=1,how="all")
print(new_data)
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 java NaN 45.6 James Gosling
1 python 1991年 67.0 NaN
2 NaN 1972年 NaN Dennis MacAlistair Ritchie
3 js NaN NaN Brendan Eich
4 php 2012年 NaN Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
# 結果解析:通過設置 how="all" 因為原數據不存在全為 NaN 的數據列,因此并沒有進行數據的過濾,輸出為原數據集
# 4. thresh=4 只保留含有4個及4個以上的非缺失值的數據
new_data= data.dropna(axis=1,thresh=4)
print(new_data)
# --- 輸出結果 ---
編程語言 推出時間 主要創始人
0 java NaN James Gosling
1 python 1991年 NaN
2 NaN 1972年 Dennis MacAlistair Ritchie
3 js NaN Brendan Eich
4 php 2012年 Rasmus Lerdorf
5 C++ 1983年 Bjarne Stroustrup
# 結果解析:因為"價格"這一列只有3個非缺失值的數據,因此設置 thresh=4,會將該列過濾掉。
# 5. subset 指定要過濾的數據列
new_data= data.dropna(axis=0,subset=["價格","主要創始人"])
print(new_data)
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 java NaN 45.6 James Gosling
5 C++ 1983年 75.0 Bjarne Stroustrup
# 結果解析:這里通過 subset 指定過濾"價格""主要創始人"列中存在 NaN 數據的行,通過結果可以看到,過濾掉了行索引為1,2,3,4的行。
3.2 fillna () 函數
該函數用于填充缺失值的操作,返回一個新的數據集,該函數提供了豐富的參數可供設置,下面列舉了常用的幾個參數:
參數名 | 說明 |
---|---|
value | 指定用什么值去填充 |
method | 填充的方式,ffill 用前一個非缺失值填充這個缺失值,bfill 用下一個非缺失值填充這個缺失值,None 默認的,指定一個缺失值去填充 |
axis | 修改填充的方向 ,默認是 axis=0 在列的方向填充 |
limit | 指定填充的個數,在某個方向如果存在多個連續的缺失值,指定填充的幾個 |
下面通代碼程序來看一個每個參數的具體使用方式:
# 導入pandas包
import pandas as pd
data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第11小節/execl數據demo.xlsx"
# 解析數據
data = pd.read_excel(data_path)
print(data)
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 java NaN 45.6 James Gosling
1 python 1991年 67.0 NaN
2 NaN 1972年 NaN Dennis MacAlistair Ritchie
3 js NaN NaN Brendan Eich
4 php 2012年 NaN Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
# 1. 直接設置 value 指定填充的內容
new_data= data.fillna("###")
print(new_data)
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 java ### 45.6 James Gosling
1 python 1991年 67 ###
2 ### 1972年 ### Dennis MacAlistair Ritchie
3 js ### ### Brendan Eich
4 php 2012年 ### Rasmus Lerdorf
5 C++ 1983年 75 Bjarne Stroustrup
# 結果解析:通過設置填充的值為 ### ,可以看到原數據集中的缺失值都被填充了該字符
# 2. 設置 method 填充的方向
new_data= data.fillna(method="bfill")
print(new_data)
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 java 1991年 45.6 James Gosling
1 python 1991年 67.0 Dennis MacAlistair Ritchie
2 js 1972年 75.0 Dennis MacAlistair Ritchie
3 js 2012年 75.0 Brendan Eich
4 php 2012年 75.0 Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
# 結果解析:這里設置了填充的方式為 bfill ,默認的 axis=0 是在列上,表示用這一列的下一行的非缺失值填充這個缺失值,通過輸出結果可看到,缺失值均被填上了內容,這里要注意一點,如果下一個數據為 NaN,則會繼續往下找,直到找到一個非缺失值的數據來填充。
# 3. 設置 axis=1 在橫向上進行填充
new_data= data.fillna(axis=1,method="bfill")
print(new_data)
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 java 45.6 45.6 James Gosling
1 python 1991年 67 NaN
2 1972年 1972年 Dennis MacAlistair Ritchie Dennis MacAlistair Ritchie
3 js Brendan Eich Brendan Eich Brendan Eich
4 php 2012年 Rasmus Lerdorf Rasmus Lerdorf
5 C++ 1983年 75 Bjarne Stroustrup
# 結果解析:這里程序中設置了 axis 為橫向,method 為 bfill ,通過輸出結果可以看到為 NaN 的數據,用他后面的非缺失值進行了填充,如果他后面沒有數據,則不進行填充,仍然為 NaN。
# 4. limit 指定出現連續的缺失值,填充的數量
new_data= data.fillna(axis=0,method="bfill",limit=2)
print(new_data)
# --- 輸出結果 ---
編程語言 推出時間 價格 主要創始人
0 java 1991年 45.6 James Gosling
1 python 1991年 67.0 Dennis MacAlistair Ritchie
2 js 1972年 NaN Dennis MacAlistair Ritchie
3 js 2012年 75.0 Brendan Eich
4 php 2012年 75.0 Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
# 結果解析:通過設置 limit=2 指定出現連續的缺失值只填充2個數據,這里可以看到在"價格"列中原數據出現的連續三個 NaN 這里按列的方向,只填充了兩個數據。
3. 小結
本節課程我們主要學習了 Pandas 檢測數據集中存在缺失值的方法,同時學習了 Pandas 對缺失值的過濾操作和填充缺失值的方法。本節課程的重點如下:
- isnull () 函數和 notnull () 函數對缺失值的檢測操作和檢測返回結果;
- dropna () 函數對缺失值的過濾操作,以及其中常用參數的設置方式;
- fillna () 函數對缺失值的填充操作,以及其中常用參數的設置方式。