3.5 處理缺失值

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章