3.5 處理缺失值
涉及的缺失值主要有三種形式: null NaN NA
選擇處理缺失值的方法
- 用覆蓋全局的掩碼
- 用特定的標籤值表示缺失值
Pandas的缺失值
採用標籤值表示缺失值
None:Python對象類型的缺失值
是Python單體對象,在代碼中表示缺失值,只能用於Object對象組成的數組中的對象,不能用作任何np或pd數組類型的缺失值。
import numpy as np
import pandas as pd
vals1 = np.array([1, None, 3, 4])
vals1 # 由於有None,數組對象類型爲Python的Object類型
array([1, None, 3, 4], dtype=object)
# Python類型運算性能較低,而且包括None對象將導致數值運算錯誤
vals1.sum()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-3-57ce7f3f1935> in <module>() 1 # Python類型運算性能較低,而且包括None對象將導致數值運算錯誤 ----> 2 vals1.sum() c:\program files\python36-32\lib\site-packages\numpy\core\_methods.py in _sum(a, axis, dtype, out, keepdims) 30 31 def _sum(a, axis=None, dtype=None, out=None, keepdims=False): ---> 32 return umr_sum(a, axis, dtype, out, keepdims) 33 34 def _prod(a, axis=None, dtype=None, out=None, keepdims=False): TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
NaN:數值類型的缺失值
是在任何系統中都兼容的特殊浮點數:
vals2 = np.array([1, np.nan, 3, 4])
vals2 # 類型會爲浮點數
array([ 1., nan, 3., 4.])
vals2.dtype
dtype('float64')
可將NaN看成“數據病毒”:任何數與其運算的結果均爲NaN:
1 + np.nan
nan
0 * np.nan
nan
vals2.sum(), vals2.min(), vals2.max()
c:\program files\python36-32\lib\site-packages\numpy\core\_methods.py:29: RuntimeWarning: invalid value encountered in reduce return umr_minimum(a, axis, None, out, keepdims) c:\program files\python36-32\lib\site-packages\numpy\core\_methods.py:26: RuntimeWarning: invalid value encountered in reduce return umr_maximum(a, axis, None, out, keepdims)
(nan, nan, nan)
np提供了特殊的累計函數,可以忽略NaN的影響:
np.nansum(vals2), np.nanmin(vals2), np.nanmax(vals2)
(8.0, 1.0, 4.0)
Pandas 中 NaN 與 None 的差異
NaN與None在pd中可以等價交換,在適當時候會將兩者進行替換:
pd.Series([1, np.nan, 2, None])
0 1.0 1 NaN 2 2.0 3 NaN dtype: float64
# pd會將沒有標籤值的數據類型自動轉換爲NaN,如整數的np.nan轉換爲浮點NaN
x = pd.Series(range(2), dtype=int)
x
0 0 1 1 dtype: int32
x[0] = None
x
0 NaN 1 1.0 dtype: float64
# object類型的None不會自動轉化
x = pd.Series(range(2), dtype=object)
x
0 0 1 1 dtype: object
x[0] = None
x
0 None 1 1 dtype: object
處理缺失值
幾個方法:
- isnull() 創建一個布爾類型的掩碼標籤缺失值
- notnull() 也創建布爾類型的掩碼,結果與isnull操作相反
- dropna() 返回一個剔除缺失值的數據
- fillna() 返回一個填充了缺失值的數據副本
發現缺失值
方法isnull()和notnull()
data = pd.Series([1, np.nan, 'hello', None])
data.isnull()
0 False 1 True 2 False 3 True dtype: bool
data.notnull()
0 True 1 False 2 True 3 False dtype: bool
# 布爾類型掩碼數組可以直接作爲Series或DF的索引使用
data[data.notnull()]
0 1 2 hello dtype: object
剔除缺失值
data.dropna()
0 1 2 hello dtype: object
# 在DF上使用要設置一些參數
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只能剔除包含缺失值數據的整行或整列數據
# 默認剔除任何包含缺失值的整行
df.dropna()
0 | 1 | 2 | |
---|---|---|---|
1 | 2.0 | 3.0 | 5 |
# 剔除任何包含缺失值的整列,要用參數
df.dropna(axis='columns')
2 | |
---|---|
0 | 2 |
1 | 5 |
2 | 6 |
按照行或列中缺失值的數量來剔除缺失值,參數how和thresh
# 參數how默認爲any,即任何缺失值存在則剔除
# 可將how設置爲all,即行或列全爲缺失值才剔除
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 |
# thresh參數,設置行或列中、非缺失值(即有用數據)的最小數量
df.dropna(axis='rows', thresh=3)
0 | 1 | 2 | 3 | |
---|---|---|---|---|
1 | 2.0 | 3.0 | 5 | NaN |
填充缺失值
fillna方法可以返回填充了缺失值後的數組副本
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
# 可用缺失值前面的有效值從前往後填充(forwad-fill)
data.fillna(method='ffill')
a 1.0 b 1.0 c 2.0 d 2.0 e 3.0 dtype: float64
# 也可用缺失值後面的有效值從後往前填充(back-fill)
data.fillna(method='bfill')
a 1.0 b 2.0 c 2.0 d 3.0 e 3.0 dtype: float64
# df用法類似,但要設置座標軸參數axis
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 |