Kaggle 數據清洗挑戰 Day 1 - 手把手教你五步處理缺失值

前些天報名參加了 Kaggle 的 Data Cleaning 5天挑戰,5天的任務如下:

  • Day 1: Handling missing values
  • Day 2: Data scaling and normalization
  • Day 3: Cleaning and parsing dates
  • Day 4: Fixing encoding errors (no more messed up text fields!)
  • Day 5: Fixing inconsistent data entry & spelling errors

今天是第一天,任務是處理數據集中的缺失值。活動的主持人 Rachael Tatman 給出的操作步驟如下:

  1. Take a first look at the data
  2. See how many missing data points we have
  3. Figure out why the data is missing
  4. Drop missing values
  5. Filling in missing values

我們一步一步來進行操作~


1、觀察數據

首先我們在 notebook 中載入需要清理的數據集,數據集的位置可以在本地也可以在伺服器上。今天官方例子中的數據集是關於美國橄欖球比賽的,然後我們動手去做的是關於舊金山建築許可證的數據集。

引入 pandas 和 numpy 包,從給出的路徑讀數據集,

# modules well useimport pandas as pdimport numpy as np# read in all our datasf_permits = pd.read_csv("../input/building-permit-applications-data/Building_Permits.csv")# set seed for reproducibilitynp.random.seed(0)

然後用 sample(10) 方法隨機抽取數據集中的 10 條數據,結果中有很多數據格被標記了 "NaN" ,這些就是我們需要處理的缺失值。

sf_permits.sample(10)


2、觀察缺失值的數量

現在我們知道了數據集中存在缺失值,再來看看每一個 column 下缺失值的具體數量(由於 column 過多我們只選了前 15 列)。

# get the number of missing data points per columnmissing_values_count = sf_permits.isnull().sum()# look at the # of missing points in the first ten columnsmissing_values_count[0:15]

然後可以進一步看看數據集中缺失值的數目佔總數的百分比,結果約為 26.26%,四分之一的數據都缺失了!

# how many total missing values do we have?total_cells = np.product(sf_permits.shape)total_missing = missing_values_count.sum()# percent of data that is missing(total_missing/total_cells) * 100


3、分析出現缺失值的原因

這一部分的重點之一是我們對數據的直覺,Rachael 所用的說法是 "data intuition",也就是說我們需要搞清楚我們面對的數據集為什麼如此,以及對我們後續的數據分析會有什麼樣的影響。由於缺乏經驗,入門者這部分可能比較困擾。我們需要考慮的問題之一是:

某個數據的缺失是因為它沒有被記錄還是根本不存在?

如果一個數據值缺失是因為它根本不存在,那麼我們就沒有必要去猜它可能的值,我們需要做的就是讓它繼續為 NaN;如果一個數據值缺失是因為沒有被記錄,我們就應該基於與它同行同列的其他值,來猜想它的可能值。

拿當前的數據集做例子,我們來看一下 Street Number Suffix 和 Zipcode 的缺失值:

missing_values_count = sf_permits.isnull().sum()missing_values_count[[Street Number Suffix, Zipcode]]

我們看到 Street Number Suffix 下有大量缺失值,由於它對地址來說並不是一個普遍存在的數據,所以我猜想它的缺失值根本不存在;有少量的 Zipcode 數據缺失,由於每個地址的郵編一定存在,所以它應該是沒有被記錄。


4、剔除缺失值

如果你實在急於做分析,可以採取的方案之一就是剔除掉任何包含缺失值的行或列。但這種方法是並不推薦,要想得到更好的分析結果,還是要先合理地處理缺失值。

如果確定想要剔除掉含有缺失值的數據行,可以直接使用 pandas 的 dropna() 方法:

# remove all the rows that contain a missing valuesf_permits.dropna()

但是我們得到的結果是 0 rows × 43 columns,因為每一行都存在缺失值!

再剔除含有缺失值的數據列:

# remove all columns with at least one missing valuecolumns_with_na_dropped = sf_permits.dropna(axis=1)columns_with_na_dropped.head()

看一下剔除空值前後的 column 數目對比:

# just how much data did we lose?print("Columns in original dataset: %d
" % sf_permits.shape[1])print("Columns with nas dropped: %d" % columns_with_na_dropped.shape[1])


5、自動補全缺失值

除了直接 drop 掉含有缺失值的行或列,另一個方案是去補全缺失的值。這部分我們先截取一部分 column 的數據進行處理,便於觀察。

# get a small subset of the sf_permits datasetsubset_sf_permits = sf_permits.loc[:,"Street Number Suffix":"Issued Date"].head()subset_sf_permits

如果數據的類型都是數字,我們可以考慮把所有的缺失值都填為 0:

# replace all NAs with 0subset_sf_permits.fillna(0)

但該數據集中,有 string 型的數據,還有另一種選擇就是將空值置為與它相鄰的下一行對應的數據,沒有下一行數據就置為 0:

# comes directly after it and then subset_sf_permits.fillna(method = "bfill", axis=0).fillna("0")

處理不同類型的數據集,需要採取不同的方法,還可以用相應 column 的平均值來補全該列的缺失值等。

這就是 5 Day Challenge 第一天的內容,總地來說是非常基礎的清洗數據方法,完畢~


推薦閱讀:

用Python下載Kaggle數據
Kaggle進階系列:zillow競賽特徵提取與模型融合(LB~0.644)
Python決策樹模型做 Titanic數據集預測並可視化(一)
kaggle小黃車競賽 得分:0.41038
Kaggle 比賽整理匯總

TAG:數據分析 | 數據清洗 | Kaggle |