文章目錄
[ Pandas version: 1.0.1 ]
四、處理缺失值
(一)選擇處理缺失值的方法
在數據表或 DataFrame 中有很多識別缺失值的方法。一般情況下可以分爲兩種:
- 一種方法是通過一個覆蓋全局的掩碼表示缺失值
- 另一種方法是用一個標籤值表示缺失值
(二)Pandas的缺失值
Pandas用標籤方法表示缺失值,包括兩種Python原有的缺失值:浮點數據類型的 NaN 值,以及Python的 None 對象。
1. None: Python對象類型的缺失值
Pandas可以使用的第一種缺失值標籤是 None,它是Python單體對象,經常在代碼中表示缺失值。
由於 None 是一個Python對象,所以不能作爲任何 NumPy/Pandas 數組類型的缺失值,只能用於’object’數組類型(由Python對象構成的數組)
import numpy as np
import pandas as pd
vals1 = np.array([1, None, 3, 4])
vals1 #輸出:array([1, None, 3, 4], dtype=object)
# dtype=object表示NumPy認爲這個數組是Python對象構成的。
# 雖然這種類型在某些情景中很有用,對數據的任何操作最終都會在Python層面完成。
# 但是在進行常見的快速操作時,這種類型比其他與原生類型數組要消耗更多的資源。
使用Python對象構成的數組意味着如果對一個包含 None 的數組進行累計操作(如sum(), min())會出現類型錯誤 TypeError
因此,在Python中沒有定義整數與 None 之間的運算。
2. NaN: 數值類型的缺失值
另一種缺失值的標籤是 NaN(全稱 Not a Number,不是一個數字),是一種按照IEEE浮點數標準設計、在任何系統中都兼容的特殊浮點數。
vals2 = np.array([1, np.nan, 3, 4])
vals2 #輸出:array([ 1., nan, 3., 4.])
vals2.dtype #輸出:dtype('float64')
# Numpy會爲這個數組選擇一個原生浮點類型,意味着這個數組會被編譯成C代碼從而實現快速操作
NaN 會將與它接觸過的數據同化,無論和 NaN 進行何種操作,最終結果都是NaN。
1 + np.nan #輸出:nan
0 * np.nan #輸出:nan
# 雖然這些累計操作的結果定義時合理的(無異常),但是並非總是有效的:
vals2.sum(), vals2.min(), vals2.max() #輸出:(nan, nan, nan)
Numpy提供一些特殊的累計函數,可以忽略缺失值的影響:
np.nansum(vals2), np.nanmin(vals2), np.nanmax(vals2) #輸出:(8.0, 1.0, 4.0)
NaN 是一種特殊的浮點數,不是整數、字符串以及其他數據類型。
3. Pandas中 NaN 與 None 的差異
Pandas把 NaN 和 None 看成是可以等價交換的,在適當的時候會將兩者進行替換:Pandas會將沒有標籤值的數據類型自動轉換爲 NA 。
除了將整型數組的缺失值強制轉換爲浮點數,Pandas還會自動將 None 轉換爲 NaN。
pd.Series([1, np.nan, 2, None])
# 0 1.0
# 1 NaN
# 2 2.0
# 3 NaN
# dtype: float64
x = pd.Series(range(2), dtype=int)
# 0 0
# 1 1
# dtype: int64
x[0] = None
# 0 NaN
# 1 1.0
# dtype: float64
Pandas對不同類型缺失值的強制轉換規則
類型 缺失值轉換規則 NA標籤值
floating 浮點型 無變化 np.nan
object 對象類型 無變化 None 或 np.nan
integer 整數類型 強制轉換爲 float64 np.nan
boolean 布爾類型 強制轉換爲 object None 或 np.nan
# 注:Pandas中字符串類型的數據通常是用object類型存儲
(三)處理缺失值
Pandas提供了一些方法來發現、剔除、替換數據結構中的缺失值
isnull() # 創建一個布爾類型的掩碼標籤缺失值
notnull() # 與isnull()操作相反
dropna() # 返回一個剔除缺失值的數據
fillna() # 返回一個填充了缺失值的數據副本
1. 發現缺失值
Pandas數據結構有兩種方法可以發現缺失值:isnull()
和notnull()
,每種方法都返回布爾類型的掩碼數據。
data = pd.Series([1, np.nan, 'hello', None])
data
# 0 1
# 1 NaN
# 2 hello
# 3 None
# dtype: object
data.isnull()
# 0 False
# 1 True
# 2 False
# 3 True
# dtype: bool
# 布爾類型掩碼數組可以直接作爲Series或DataFrame索引使用
data[data.notnull()]
# 0 1
# 2 hello
# dtype: object
2. 剔除缺失值
除了前面的掩碼方法,還有兩種缺失值處理方法:dropna()
(剔除缺失值)和fillna()
(填充缺失值)
data.dropna()
# 0 1
# 2 hello
# dtype: object
對於DataFrame的參數設置:
默認情況下,dropna()會剔除任何包含缺失值的整行數據。
DataFrame中可以設置按不同座標軸剔除缺失值,如axis=1
或axis='columns'
會剔除任何包含缺失值的整列數據。
有時候只需要剔除全部或絕大多數時缺失值的行或列,可以通過設置how或thresh參數來滿足(設置剔除行或列缺失值的數量閾值)
- 默認設置
how='any'
(只要有缺失值就剔除整行或整列) - 可以設置
how='all'
(只剔除全部是缺失值的行或列) - 通過
thresh
參數設置行或列中非缺失值的最小數量
df = pd.DataFrame([[1, np.nan, 2], [2, 3, 5], [np.nan, 4, 6]])
df
# 0 1 2
# 0 1.0 NaN 2
# 1 2.0 3.0 5
# 2 NaN 4.0 6
df.dropna()
# 0 1 2
# 1 2.0 3.0 5
df.dropna(axis='columns')
# 2
# 0 2
# 1 5
# 2 6
df[3] = np.nan
df
# 0 1 2 3
# 0 1.0 NaN 2 NaN
# 1 2.0 3.0 5 NaN
# 2 NaN 4.0 6 NaN
df.dropna(axis='columns', how='all')
# 0 1 2
# 0 1.0 NaN 2
# 1 2.0 3.0 5
# 2 NaN 4.0 6
df.dropna(axis='rows', thresh=3) #每行至少3個非缺
# 0 1 2 3
# 1 2.0 3.0 5 NaN
3. 填充缺失值
有時需要把缺失值替換成有效的數值。有效數值包括單獨數值,經過填充或轉換得到的值。
可以通過isnull()
方法建立掩碼來填充缺失值,Pandas也提供了fillna()
方法(返回填充了缺失值後的數組副本)
fillna()方法:
- 可以用單獨數值填充
- 可以用缺失值前面的有效值來從前往後填充(forward-fill):
fillna(method='ffill')
- 可以用缺失值後面的有效值來從後往前填充(back-fill):
fillna(method='bfill')
- DataFrame操作時可以設置座標軸參數
- 注意:如果從前往後填充時,需要填充的缺失值前面沒有值,那麼它仍然是缺失值
data = pd.Series([1, np.nan, 2, None, 3], index=list('abcde'))
data
# a 1.0
# b NaN
# c 2.0
# d NaN
# e 3.0
# dtype: float64
# 單獨數值填充
data.fillna(0)
# a 1.0
# b 0.0
# c 2.0
# d 0.0
# e 3.0
# dtype: float64
# 從前往後填充
data.fillna(method='ffill')
# a 1.0
# b 1.0
# c 2.0
# d 2.0
# e 3.0
# dtype: float64
# 從後往前填充
data.fillna(method='bfill')
# a 1.0
# b 2.0
# c 2.0
# d 3.0
# e 3.0
# dtype: float64
# DataFrame按座標軸填充
df
# 0 1 2 3
# 0 1.0 NaN 2 NaN
# 1 2.0 3.0 5 NaN
# 2 NaN 4.0 6 NaN
df.fillna(method='ffill', axis=1)
# 0 1 2 3
# 0 1.0 1.0 2.0 2.0
# 1 2.0 3.0 5.0 5.0
# 2 NaN 4.0 6.0 6.0
Pandas 相關閱讀:
[Python3] Pandas v1.0 —— (一) 對象、數據取值與運算
[Python3] Pandas v1.0 —— (二) 處理缺失值 【本文】
[Python3] Pandas v1.0 —— (三) 層級索引
[Python3] Pandas v1.0 —— (四) 合併數據集
[Python3] Pandas v1.0 —— (五) 累計與分組
[Python3] Pandas v1.0 —— (六) 數據透視表
[Python3] Pandas v1.0 —— (七) 向量化字符串操作
[Python3] Pandas v1.0 —— (八) 處理時間序列
[Python3] Pandas v1.0 —— (九) 高性能Pandas: eval()與query()
總結自《Python數據科學手冊》