1. 程式人生 > >Pandas處理資料缺失值

Pandas處理資料缺失值

寫在篇前

  在資料處理實踐中,資料不可能十全十美,總會由於總總原因,比如不可測、測量結果丟失等原因使得部分資料缺失,處理缺失值的策略一般分為以下兩種:

  1. 通過維持一個覆蓋全域性的掩碼錶示缺失值

      a)維持一個與資料表大小相同的bool值陣列

      b)用一個bit表示有缺失值的區域性狀態

  2. 用一個標籤值(sentinel value)表示缺失值

  一般而言,不存在所謂的最佳選擇,不同的程式語言和系統會選擇不同的處理方式,在pandas中選用了標籤的方式標示缺失值,包括浮點型別缺失值NaN、Python單體物件None。好吧,talk is cheap,show you the code

.

缺失值標示方法

None標示缺失值

>>> import numpy as np
>>> vals1 = np.array([1, None, 3, 4])
>>> vals1

array([1, None, 3, 4], dtype=object)

# None只能用於object型別陣列,這將會比原生int,float型別更加消耗資源,所以謹慎使用

NaN標示缺失值

>>> vals2 = np.array([1, np.nan, 3, 4])
>>> vals2
array([ 1.
, nan, 3., 4.]) >>> vals2.dtype dtype('float64') # 在這種方式中,將以原生型別float64作為陣列型別,將具有更加好的效能 # 原因是這會被編譯C程式碼,從而實現快速操作 # 關於nan還需要注意幾個問題 >>> vals2.sum() nan >>> np.nansum(vals2) 8.0 >>> vals2.min() nan >>> np.nanmin(vals2) 1.0

Pandas中None與NaN的差異

   Pandas把它們看成是可以等價交換的,在適當的時候會將兩者進行替換。

>>> pd.Series([1, np.nan, 2, None])
0    1.0
1    NaN
2    2.0
3    NaN
dtype: float64

缺失值處理方法

  • isnull()   建立一個布林型別的掩碼標籤缺失值
  • notnull()   與 isnull() 操作相反
  • dropna()   返回一個剔除缺失值的資料
  • fillna()   返回一個填充了缺失值的資料副本

發現缺失值

>>> 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

# 應用
>>> data[data.notnull()]
0        1
2    hello
dtype: object

剔除缺失值

# 剔除缺失值,主要用dropna()函式

def dropna(self, axis=0, how='any', thresh=None, subset=None,
               inplace=False)
# axis 標示軸向,0代表行,1代表列
# how 有選項 anyall
# threshhow選項互斥使用,指定一行或一列非缺失值的最小個數
# subset array-like, optional,表示只將非axis軸所指定行或列納入剔除考慮
# inplace 表示是否要建立新的副本,個人建議為True,減少資源消耗


# subset引數稍微不好理解,show u the code
df = pd.DataFrame([
    [1, np.nan, 2, 5],
    [2, 3, 5, 6],
    [np.nan, 4, 6, 7]
])

print(df.dropna(axis=0, how='any', subset=[0, 3]))output:0    1  2  3
0  1.0  NaN  2  5
1  2.0  3.0  5  6

解析:在本例中,明明指定了按行剔除,只要有any缺失值就踢除改行,但是第一行卻保留了,納尼?這就是subset的作用,因為我們在subset引數中指定了是看第03列有沒有缺失值從而決定是否剔除該列。

填充缺失值

  資料是寶貴的,有時候我們並不忍心刪除一些記錄,這時候我們就需要考慮用何種方式對缺失值進行修復,這就是缺失值填充。其實缺失值填充的策略非常之多,這裡主要介紹Pandas內建的填充方式,具體用哪種方式,這也許真的需要具體任務具體分析。

# 函式主要引數
def fillna(self, value=None, method=None, axis=None, inplace=False)

# value 表示填充特定值
# method 表示填充方式,與value互斥使用,有從後往前填充(method='ffill'),從前往後填充(method='bfill')
# axis 表示軸向,在ffillbfill方式中有區別,注意體會
# inplace 表示是否要建立新的副本,個人建議為True,減少資源消耗

# 例子
data = pd.Series([1, np.nan, 2, None, 3], index=list('abcde'))
print(data.fillna(value=0))

a    1.0
b    0.0
c    2.0
d    0.0
e    3.0
dtype: float64

總結

  在這一篇中,主要總結了pandas中的缺失值處理方式,但是實際上處理缺失值的方式非常靈活,需要具體任務具體分析,甚至自定義一種處理方式。要自定義處理,就需要掌握好一些pandas資料集的處理技巧,可以參考我之前的部落格pandas 資料分析常用技巧,比如其中的applyapplymapmap等方法對於定義高階資料操作極其方便、重要。