python,不管你懂沒懂,反正妹子是搞懂了

轉載請註明:知乎專欄《給妹子講python》--醬油哥

【要點搶先看】

1.Pandas中缺失值的表徵方式及運算處理規則2.如何發現缺失值3.如何對缺失值進行丟棄處理4.如何對缺失值進行填充處理

現實中的數據,往往不如我們在例子中演示的那般乾淨、整齊,經常會出現數據缺失的現象,今天這一集,我們就來說說Pandas中缺失值的處理方法。

python中採用一種NaN(Not a Number)標籤來表示缺失值,NaN本質上是一種浮點數類型:

import pandas as pdimport numpy as npvar = np.array([1, np.nan, 3, 4])print(var)print(var.dtype)[ 1. nan 3. 4.]float64

運行結果很清楚的表明,NumPy為缺失值選擇了一種原生類型的數據類型:浮點型。

nan缺失值類型有一個重要的特性,就是任何數與之運算,其結果都是nan。

import pandas as pdimport numpy as npvar = np.array([1, 2, np.nan, 4])print(np.nan + 1)print(np.nan * 5)print(var.sum())print(var.max())nannannannan

當然,如果在NumPy中忽略掉nan缺失值進行一些運算,也是有辦法的,NumPy有專門的函數:

import pandas as pdimport numpy as npvar = np.array([1, 2, np.nan, 4])print(np.nansum(var))print(np.nanmax(var))print(np.nanmin(var))7.04.01.0

Pandas數據類型對缺失值的處理也是類似的,NaN表示缺失值時,他的類型是浮點數,如果表示缺失對象時,他的類型是object類型。

首先舉一個浮點類型缺失值的例子,將整數型Series中的某值設置為缺失型,整個Series將強制變成浮點型:

import pandas as pdimport numpy as npvar = pd.Series([1,2],dtype=int)print(var)var[0] = np.nanprint(var)0 11 2dtype: int320 NaN1 2.0dtype: float64

表示缺失對象的場景我們也可以舉一個例子,如果Series中的數據類型是字元串,由於字元串是object類型,因此將該類型的Series中的某個字元串數據設置為缺失型,整個類型仍是object類型。

import pandas as pdimport numpy as npvar = pd.Series([aa,bb])print(var)var[0] = np.nanprint(var)0 aa1 bbdtype: object0 NaN1 bbdtype: object

瞭解了缺失值的基本知識,那重點來了,使用Pandas工具時如何處理缺失值呢?

首先是如何發現缺失值。我們可以用isnull()和notnull()兩種方法來發現缺失值。

import pandas as pdimport numpy as npvar = pd.Series([aa,np.nan,1,np.nan])print(var.isnull())print(var.notnull())0 False1 True2 False3 Truedtype: bool0 True1 False2 True3 Falsedtype: bool

這兩種方法,返回的都是布爾型的掩碼數據,isnull()會在為空的位置上顯示True,notnull則正好相反。

這種布爾型掩碼數據可以作為一種過濾的工具:

import pandas as pdimport numpy as npvar = pd.Series([aa,np.nan,1,np.nan])print(var[var.notnull()])0 aa2 1dtype: object

那麼自然,下一步我們就應該討論如何處理缺失值,最簡單的方法是丟棄缺失值

Series數據類型對於缺失值的處理很簡單,就是簡單的丟棄相應的值:

import pandas as pdimport numpy as npvar = pd.Series([aa,np.nan,1,np.nan])print(var.dropna())0 aa2 1dtype: object

但是DataFrame就要複雜一些,他無法簡單的單獨剔除掉一個缺失值,要麼剔除缺失值所在的整行,要麼剔除掉整列,默認是剔除行,如果要剔除所在列的話,需要單獨設置axis=1的關鍵字參數。

import pandas as pdimport numpy as npdf = pd.DataFrame([[1,np.nan,2], [2,3,5], [np.nan,4,6]])print(df) #原始dfprint(df.dropna()) #丟棄缺失值所在行print(df.dropna(axis=1)) #丟棄缺失值所在列 0 1 20 1.0 NaN 21 2.0 3.0 52 NaN 4.0 6 0 1 21 2.0 3.0 5 20 21 52 6

在dropna()函數中還有一個非常重要的參數how,默認how=any,表示此行(或列)只要有一個NaN值,就要刪除所在行(或列)。當how=all是表示只有當此行(或列)全部都是NaN值時,才執行此操作。

import pandas as pdimport numpy as npdf = pd.DataFrame([[1,np.nan,2,4], [2,3,5,3], [np.nan,np.nan,np.nan,np.nan]])print(df)print(df.dropna(how=any))print(df.dropna(how=all)) 0 1 2 30 1.0 NaN 2.0 4.01 2.0 3.0 5.0 3.02 NaN NaN NaN NaN 0 1 2 31 2.0 3.0 5.0 3.0 0 1 2 30 1.0 NaN 2.0 4.01 2.0 3.0 5.0 3.0

當然還有一個更精細的thresh參數控制,他表示留下此行(或列)時,非缺失值最少需要有的個數。

import pandas as pdimport numpy as npdf = pd.DataFrame([[1,np.nan,2,4], [2,np.nan,np.nan,3], [np.nan,np.nan,np.nan,np.nan]])print(df)print(df.dropna(thresh=3)) 0 1 2 30 1.0 NaN 2.0 4.01 2.0 NaN NaN 3.02 NaN NaN NaN NaN 0 1 2 30 1.0 NaN 2.0 4.0

我們看到第二行和第三行被剔除了,因為他們的非缺失值個數不足3個

但是,有時候我們並不想因為剔除缺失值而刪掉他所在的行,因為這樣失去的有用信息就太多了,因此我們還有一種處理方法,那就是填充缺失值。

第一種方法是用指定的值來填充缺失值:

import pandas as pdimport numpy as npdf = pd.DataFrame([[11,np.nan,22,44], [22,np.nan,np.nan,33], [np.nan,np.nan,np.nan,np.nan]])print(df.fillna(0)) 0 1 2 30 11.0 0.0 22.0 44.01 22.0 0.0 0.0 33.02 0.0 0.0 0.0 0.0

在這個例子中,我們用0填充了所有的缺失值。

還有一種常見的方法,就是用相鄰的值進行填充,這在時間序列分析中相當常見,自然,可以用前面相鄰的值向後填充,也可以用後面相鄰的值向前填充。

import pandas as pdimport numpy as npdata = pd.Series([1,np.nan,2,np.nan,3],index=list(abcde))print(data)print(data.fillna(method=ffill))print(data.fillna(method=bfill))a 1.0b NaNc 2.0d NaNe 3.0dtype: float64a 1.0b 1.0c 2.0d 2.0e 3.0dtype: float64a 1.0b 2.0c 2.0d 3.0e 3.0dtype: float64

從結果中我們很容易看懂從前往後填充以及從後往前填充的具體效果。

當然DataFrame數據類型也是同理,當然他還可以指定填充具體是沿著那個方向,下面的例子,我們指定沿著縱軸的方向,從前往後進行填充:

import pandas as pdimport numpy as npdf = pd.DataFrame([[1,np.nan,2,4], [2,3,5,3], [np.nan,5,4,np.nan]])print(df)print(df.fillna(method=ffill, axis=1)) 0 1 2 30 1.0 NaN 2 4.01 2.0 3.0 5 3.02 NaN 5.0 4 NaN 0 1 2 30 1.0 1.0 2.0 4.01 2.0 3.0 5.0 3.02 NaN 5.0 4.0 4.0

當然,如果從前往後填充,第一個值就是NaN,那自然是沒有辦法進行填充處理了。

【妹子說】沒想到對於缺失值進行處理還有這麼多講究,那看來Pandas對於實際的數據清洗工作確實考慮的非常全面。


推薦閱讀:
相關文章