第6章 pandas缺失數據(初學者需要掌握的幾種基本的數據預處理方法_缺失)

在拿到一份數據準備做挖掘建模之前,首先需要進行初步的數據探索性分析,對數據探索性分析之後要先進行一系列的數據預處理步驟。因爲拿到的原始數據存在不完整、不一致、有異常的數據,而這些“錯誤”數據會嚴重影響到數據挖掘建模的執行效率甚至導致挖掘結果出現偏差,因此首先要數據清洗。數據清洗完成之後接着進行或者同時進行數據集成、轉換、歸一化等一系列處理,該過程就是數據預處理。一方面是提高數據的質量,另一方面可以讓數據更好的適應特定的挖掘模型,在實際工作中該部分的內容可能會佔整個工作的70%甚至更多。

系列文章
第1章 Pandas基礎操作(使用pandas進行數據分析,從小白逆襲大神,你會了嗎?)
第2章 精通pandas索引操作(使用pandas進行數據分析,從小白逆襲大神,你會了嗎?)
第3章 Pandas 分組(使用pandas進行數據分析,從小白逆襲大神,你會了嗎?)
第4章 精通pandas變形操作(使用pandas進行數據分析,從小白逆襲大神,你會了嗎?)
第5章 精通pandas合併操作(使用pandas進行數據分析,從小白逆襲大神,你會了嗎?)

第6章 缺失數據

在接下來的兩章中,會接觸到數據預處理中比較麻煩的類型,即缺失數據和文本數據(尤其是混雜型文本)

Pandas在步入1.0後,對數據類型也做出了新的嘗試,尤其是Nullable類型和String類型,瞭解這些可能在未來成爲主流的新特性是必要的

import pandas as pd
import numpy as np
df = pd.read_csv('data/table_missing.csv')
df.head()

在這裏插入圖片描述

一、缺失觀測及其類型

1. 瞭解缺失信息

(a)isna和notna方法

對Series使用會返回布爾列表

df['Physics'].isna().head()

在這裏插入圖片描述

df['Physics'].notna().head()

在這裏插入圖片描述
對DataFrame使用會返回布爾表

df.isna().head()

在這裏插入圖片描述
但對於DataFrame我們更關心到底每列有多少缺失值

df.isna().sum()

在這裏插入圖片描述
此外,可以通過第1章中介紹的info函數查看缺失信息

df.info()

在這裏插入圖片描述
(b)查看缺失值的所以在行

以最後一列爲例,挑出該列缺失值的行

df[df['Physics'].isna()]

在這裏插入圖片描述
(c)挑選出所有非缺失值列

使用all就是全部非缺失值,如果是any就是至少有一個不是缺失值

df[df.notna().all(1)]

在這裏插入圖片描述

2. 三種缺失符號

(a)np.nan

np.nan是一個麻煩的東西,首先它不等與任何東西,甚至不等於自己
在這裏插入圖片描述

在用equals函數比較時,自動略過兩側全是np.nan的單元格,因此結果不會影響

df.equals(df)

在這裏插入圖片描述
其次,它在numpy中的類型爲浮點,由此導致數據集讀入時,即使原來是整數的列,只要有缺失值就會變爲浮點型
在這裏插入圖片描述
此外,對於布爾類型的列表,如果是np.nan填充,那麼它的值會自動變爲True而不是False

pd.Series([1,np.nan,3],dtype='bool')

在這裏插入圖片描述
但當修改一個布爾列表時,會改變列表類型,而不是賦值爲True

s = pd.Series([True,False],dtype='bool')
s[1]=np.nan
s

在這裏插入圖片描述

在所有的表格讀取後,無論列是存放什麼類型的數據,默認的缺失值全爲np.nan類型

因此整型列轉爲浮點;而字符由於無法轉化爲浮點,因此只能歸併爲object類型(‘O’),原來是浮點型的則類型不變
在這裏插入圖片描述
(b)None

None比前者稍微好些,至少它會等於自身

None == None

在這裏插入圖片描述
它的布爾值爲False

pd.Series([None],dtype='bool')

在這裏插入圖片描述
修改布爾列表不會改變數據類型

s = pd.Series([True,False],dtype='bool')
s[0]=None
s

在這裏插入圖片描述
在傳入數值類型後,會自動變爲np.nan

type(pd.Series([1,None])[1])

在這裏插入圖片描述
只有當傳入object類型是保持不動,幾乎可以認爲,除非人工命名None,它基本不會自動出現在Pandas中

type(pd.Series([1,None],dtype='O')[1])

在這裏插入圖片描述
在a使用equals函數時不會被略過,因此下面的情況下返回False

pd.Series([None]).equals(pd.Series([np.nan]))

在這裏插入圖片描述
(c)NaT

NaT是針對時間序列的缺失值,是Pandas的內置類型,可以完全看做時序版本的np.nan,與自己不等,且使用equals是也會被跳過

s_time = pd.Series([pd.Timestamp('20120101')]*5)
s_time

在這裏插入圖片描述

s_time[2] = None
s_time

在這裏插入圖片描述

s_time[2] = np.nan
s_time

在這裏插入圖片描述

s_time[2] = pd.NaT
s_time

在這裏插入圖片描述

type(s_time[2])

在這裏插入圖片描述

s_time[2] == s_time[2]

在這裏插入圖片描述

s_time.equals(s_time)

在這裏插入圖片描述

s = pd.Series([True,False],dtype='bool')
s[1]=pd.NaT
s

在這裏插入圖片描述

3. Nullable類型與NA符號

這是Pandas在1.0新版本中引入的重大改變,其目的就是爲了(在若干版本後)解決之前出現的混亂局面,統一缺失值處理方法

“The goal of pd.NA is provide a “missing” indicator that can be used consistently across data types (instead of np.nan, None or pd.NaT depending on the data type).”——User Guide for Pandas v-1.0

官方鼓勵用戶使用新的數據類型和缺失類型pd.NA

(a)Nullable整形
對於該種類型而言,它與原來標記int上的符號區別在於首字母大寫:‘Int’

s_original = pd.Series([1, 2], dtype="int64")
s_original

在這裏插入圖片描述

s_new = pd.Series([1, 2], dtype="Int64")
s_new

在這裏插入圖片描述
它的好處就在於,其中前面提到的三種缺失值都會被替換爲統一的NA符號,且不改變數據類型

s_original[1] = np.nan
s_original

在這裏插入圖片描述

s_new[1] = np.nan
s_new

在這裏插入圖片描述

s_new[1] = None
s_new

在這裏插入圖片描述

s_new[1] = pd.NaT
s_new

在這裏插入圖片描述
(b)Nullable布爾

對於該種類型而言,作用與上面的類似,記號爲boolean

s_original = pd.Series([1, 0], dtype="bool")
s_original

在這裏插入圖片描述

s_new = pd.Series([0, 1], dtype="boolean")
s_new

在這裏插入圖片描述

s_original[0] = np.nan
s_original

在這裏插入圖片描述

s_original = pd.Series([1, 0], dtype="bool") #此處重新加一句是因爲前面賦值改變了bool類型
s_original[0] = None
s_original

在這裏插入圖片描述

s_new[0] = np.nan
s_new

在這裏插入圖片描述

s_new[0] = None
s_new

在這裏插入圖片描述

s_new[0] = pd.NaT
s_new

在這裏插入圖片描述
需要注意的是,含有pd.NA的布爾列表在1.0.2之前的版本作爲索引時會報錯,這是一個之前的bug,現已經修復

s = pd.Series(['dog','cat'])
s[s_new]

在這裏插入圖片描述
(c)string類型

該類型是1.0的一大創新,目的之一就是爲了區分開原本含糊不清的object類型,這裏將簡要地提及string,因爲它是第7章的主題內容

它本質上也屬於Nullable類型,因爲並不會因爲含有缺失而改變類型

s = pd.Series(['dog','cat'],dtype='string')
s

在這裏插入圖片描述

s[0] = np.nan
s

在這裏插入圖片描述

s[0] = None
s

在這裏插入圖片描述
此外,和object類型的一點重要區別就在於,在調用字符方法後,string類型返回的是Nullable類型,object則會根據缺失類型和數據類型而改變

s = pd.Series(["a", None, "b"], dtype="string")
s.str.count('a')

在這裏插入圖片描述

s2 = pd.Series(["a", None, "b"], dtype="object")
s2.str.count("a")

在這裏插入圖片描述

s.str.isdigit()

在這裏插入圖片描述

s2.str.isdigit()

在這裏插入圖片描述

4. NA的特性

(a)邏輯運算
只需看該邏輯運算的結果是否依賴pd.NA的取值,如果依賴,則結果還是NA,如果不依賴,則直接計算結果
在這裏插入圖片描述

(b)算術運算和比較運算
這裏只需記住除了下面兩類情況,其他結果都是NA即可
在這裏插入圖片描述

5. convert_dtypes方法

這個函數的功能往往就是在讀取數據時,就把數據列轉爲Nullable類型,是1.0的新函數

pd.read_csv('data/table_missing.csv').dtypes

在這裏插入圖片描述

pd.read_csv('data/table_missing.csv').convert_dtypes().dtypes

在這裏插入圖片描述

二、缺失數據的運算與分組

1. 加號與乘號規則

使用加法時,缺失值爲0

s = pd.Series([2,3,np.nan,4])
s.sum()

在這裏插入圖片描述
使用乘法時,缺失值爲1

s.prod()

在這裏插入圖片描述
使用累計函數時,缺失值自動略過

s.cumsum()

在這裏插入圖片描述

s.cumprod()

在這裏插入圖片描述

s.pct_change()

在這裏插入圖片描述

2. groupby方法中的缺失值

自動忽略爲缺失值的組

df_g = pd.DataFrame({'one':['A','B','C','D',np.nan],'two':np.random.randn(5)})
df_g

在這裏插入圖片描述

df_g.groupby('one').groups

在這裏插入圖片描述

三、填充與剔除

1. fillna方法

(a)值填充與前後向填充(分別與ffill方法和bfill方法等價

df['Physics'].fillna('missing').head()

在這裏插入圖片描述

df['Physics'].fillna(method='ffill').head()

在這裏插入圖片描述

df['Physics'].fillna(method='backfill').head()

在這裏插入圖片描述
(b)填充中的對齊特性

df_f = pd.DataFrame({'A':[1,3,np.nan],'B':[2,4,np.nan],'C':[3,5,np.nan]})
df_f.fillna(df_f.mean())

在這裏插入圖片描述
返回的結果中沒有C,根據對齊特點不會被填充

df_f.fillna(df_f.mean()[['A','B']])

在這裏插入圖片描述

2. dropna方法

(a)axis參數

 df_d = pd.DataFrame({'A':[np.nan,np.nan,np.nan],'B':[np.nan,3,2],'C':[3,2,1]})
df_d

在這裏插入圖片描述

df_d.dropna(axis=0)

在這裏插入圖片描述

df_d.dropna(axis=1)

在這裏插入圖片描述
(b)how參數(可以選all或者any,表示全爲缺失去除和存在缺失去除)

df_d.dropna(axis=1,how='all')

在這裏插入圖片描述
(c)subset參數(即在某一組列範圍中搜索缺失值)

df_d.dropna(axis=0,subset=['B','C'])

在這裏插入圖片描述

四、插值(interpolation)

1. 線性插值

(a)索引無關的線性插值

默認狀態下,interpolate會對缺失的值進行線性插值

s = pd.Series([1,10,15,-5,-2,np.nan,np.nan,28])
s

在這裏插入圖片描述

s.interpolate()

在這裏插入圖片描述

s.interpolate().plot()

在這裏插入圖片描述
此時的插值與索引無關

s.index = np.sort(np.random.randint(50,300,8))
s.interpolate()
#值不變

在這裏插入圖片描述

s.interpolate().plot()
#後面三個點不是線性的(如果幾乎爲線性函數,請重新運行上面的一個代碼塊,這是隨機性導致的)

在這裏插入圖片描述
(b)與索引有關的插值

method中的index和time選項可以使插值線性地依賴索引,即插值爲索引的線性函數

s.interpolate(method='index').plot()
#可以看到與上面的區別

在這裏插入圖片描述
如果索引是時間,那麼可以按照時間長短插值,對於時間序列將在第9章詳細介紹

s_t = pd.Series([0,np.nan,10]
        ,index=[pd.Timestamp('2012-05-01'),pd.Timestamp('2012-05-07'),pd.Timestamp('2012-06-03')])
s_t

在這裏插入圖片描述

s_t.interpolate().plot()

在這裏插入圖片描述

s_t.interpolate(method='time').plot()

在這裏插入圖片描述

2. 高級插值方法

此處的高級指的是與線性插值相比較,例如樣條插值、多項式插值、阿基瑪插值等(需要安裝Scipy),方法詳情請看這裏

關於這部分僅給出一個官方的例子,因爲插值方法是數值分析的內容,而不是Pandas中的基本知識:

import pandas as pd
import numpy as np
ser = pd.Series(np.arange(1, 10.1, .25) ** 2 + np.random.randn(37))
missing = np.array([4, 13, 14, 15, 16, 17, 18, 20, 29])
ser[missing] = np.nan
methods = ['linear', 'quadratic', 'cubic']
df = pd.DataFrame({m: ser.interpolate(method=m) for m in methods})
df.plot()

在這裏插入圖片描述

3. interpolate中的限制參數

(a)limit表示最多插入多少個

s = pd.Series([1,np.nan,np.nan,np.nan,5])
s.interpolate(limit=2)

在這裏插入圖片描述
(b)limit_direction表示插值方向,可選forward,backward,both,默認前向

s = pd.Series([np.nan,np.nan,1,np.nan,np.nan,np.nan,5,np.nan,np.nan,])
s.interpolatae(limit_direction='backward')

在這裏插入圖片描述

代碼和數據地址:https://github.com/XiangLinPro/pandas

另外博主收藏這些年來看過或者聽過的一些不錯的常用的上千本書籍,沒準你想找的書就在這裏呢,包含了互聯網行業大多數書籍和麪試經驗題目等等。有人工智能系列(常用深度學習框架TensorFlow、pytorch、keras。NLP、機器學習,深度學習等等),大數據系列(Spark,Hadoop,Scala,kafka等),程序員必修系列(C、C++、java、數據結構、linux,設計模式、數據庫等等)以下是部分截圖

更多文章見本原創微信公衆號「五角錢的程序員」,我們一起成長,一起學習。一直純真着,善良着,溫情地熱愛生活。關注回覆【電子書】即可領取哦

在這裏插入圖片描述

在這裏插入圖片描述

所有巧合的是要麼是上天註定要麼是一個人偷偷的在努力。

有收穫?希望老鐵們來個三連擊,給更多的人看到這篇文章

1、給俺點個讚唄,可以讓更多的人看到這篇文章,謝謝各位親。

2、親們,關注我的原創微信公衆號「五角錢的程序員」,我們一起成長,一起學習。一直純真着,善良着,溫情地熱愛生活。關注回覆【電子書】有很多資源哦。

給大家推薦一個Github,上面非常非常多的乾貨:https://github.com/XiangLinPro/IT_book

Whatever I believed, I did; and whatever I did, I did with my whole heart and mind.

凡是我相信的,我都做了;凡是我做了的事,都是全身心地投入去做的。

關於Datawhale

Datawhale是一個專注於數據科學與AI領域的開源組織,彙集了衆多領域院校和知名企業的優秀學習者,聚合了一羣有開源精神和探索精神的團隊成員。Datawhale以“for the learner,和學習者一起成長”爲願景,鼓勵真實地展現自我、開放包容、互信互助、敢於試錯和勇於擔當。同時Datawhale 用開源的理念去探索開源內容、開源學習和開源方案,賦能人才培養,助力人才成長,建立起人與人,人與知識,人與企業和人與未來的聯結。

2020.5.22於城口

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