Python如何優雅地處理NaN

背景

很多數據不可避免的會遺失掉,或者採集的時候採集對象不願意透露,這就造成了很多NaN(Not a Number)的出現。這些NaN會造成大部分模型運行出錯,所以對NaN的處理很有必要。

方法

1、簡單粗暴地去掉

有如下dataframe,先用df.isnull().sum()檢查下哪一列有多少NaN:

import pandas as pd    df = pd.DataFrame({'a':[None,1,2,3],'b':[4,None,None,6],'c':[1,2,1,2],'d':[7,7,9,2]})  print (df)  print (df.isnull().sum())

輸出:

將含有NaN的列(columns)去掉:
data_without_NaN =df.dropna(axis=1)  print (data_without_NaN)

輸出:

2、遺失值插補法

很多時候直接刪掉列會損失很多有價值的數據,不利於模型的訓練。所以可以考慮將NaN替換成某些數,顯然不能隨隨便便替換,有人喜歡替換成0,往往會畫蛇添足。譬如調查工資收入與學歷高低的關係,有的人不想透露工資水平,但如果給這些NaN設置為0很顯然會失真。所以Python有個Imputation(插補)的方法,其中 的算法不細究。代碼如下:

from sklearn.preprocessing import Imputer    my_imputer = Imputer()  data_imputed = my_imputer.fit_transform(df)  print (type(data_imputed))  # array轉換成df  df_data_imputed = pd.DataFrame(data_imputed,columns=df.columns)  print (df_data_imputed)

輸出:

可以看出,這裡大概是用平均值進行了替換。

3、推廣的遺失值插補法

這個推廣的思想是NaN本身具有一定數據價值,譬如不愛說自己工資的被調查者是不是有什麼共性,這個時候就不能簡單的只用上面的插補法,要增加幾列,將NaN的情況記錄下來作為新的數據:

# 先複製一份愛怎麼玩怎麼玩  new_data = df.copy()    # 增加有NaN的布爾列(True/False)  cols_with_missing = (col for col in new_data.columns                                   if new_data[col].isnull().any())  for col in cols_with_missing:      new_data[col + '_was_NaN'] = new_data[col].isnull()  print (new_data)    # Imputation  my_imputer = Imputer()  new_data_imputed = my_imputer.fit_transform(new_data)  # array轉換成df  df_new_data_imputed = pd.DataFrame(new_data_imputed,columns=new_data.columns)  print (df_new_data_imputed)

輸出: