詳解pandas中缺失數(shù)據(jù)處理的函數(shù)
今天分享一篇pandas缺失值處理的操作指南!
一、缺失值類(lèi)型
在pandas
中,缺失數(shù)據(jù)顯示為NaN。缺失值有3種表示方法,np.nan
,none
,pd.NA
。
1、np.nan
缺失值有個(gè)特點(diǎn)(坑),它不等于任何值,連自己都不相等。如果用nan
和任何其它值比較都會(huì)返回nan
。
np.nan?==?np.nan >>?False
也正由于這個(gè)特點(diǎn),在數(shù)據(jù)集讀入以后,不論列是什么類(lèi)型的數(shù)據(jù),默認(rèn)的缺失值全為np.nan
。
因?yàn)?code>nan在Numpy
中的類(lèi)型是浮點(diǎn),因此整型列會(huì)轉(zhuǎn)為浮點(diǎn);而字符型由于無(wú)法轉(zhuǎn)化為浮點(diǎn)型,只能歸并為object類(lèi)型('O'),原來(lái)是浮點(diǎn)型的則類(lèi)型不變。
type(np.nan) >>?float
pd.Series([1,2,3]).dtype >>?dtype('int64') pd.Series([1,np.nan,3]).dtype >>?dtype('float64')
初學(xué)者做數(shù)據(jù)處理遇見(jiàn)object類(lèi)型會(huì)發(fā)懵,不知道這是個(gè)啥,明明是字符型,導(dǎo)入后就變了,其實(shí)是因?yàn)槿笔е祵?dǎo)致的。
除此之外,還要介紹一種針對(duì)時(shí)間序列的缺失值,它是單獨(dú)存在的,用NaT表示,是pandas
的內(nèi)置類(lèi)型,可以視為時(shí)間序列版的np.nan
,也是與自己不相等。
s_time?=?pd.Series([pd.Timestamp('20220101')]*3) s_time >>?0?2022-01-01 ???1?2022-01-01 ???2?2022-01-01 ???dtype:datetime64[ns] ----------------- s_time[2]?=?pd.NaT s_time >>?0?2022-01-01 ???1?2022-01-01 ???2?NaT ???dtype:datetime64[ns]
2、None
還有一種就是None
,它要比nan
好那么一點(diǎn),因?yàn)樗辽僮约号c自己相等。
None?==?None >>?True
在傳入數(shù)值類(lèi)型后,會(huì)自動(dòng)變?yōu)?code>np.nan。
type(pd.Series([1,None])[1]) >>?numpy.float64
只有當(dāng)傳入object
類(lèi)型時(shí)是不變的,因此可以認(rèn)為如果不是人工命名為None
的話,它基本不會(huì)自動(dòng)出現(xiàn)在pandas
中,所以None
大家基本也看不到。
type(pd.Series([1,None],dtype='O')[1]) >>?NoneType
3、NA標(biāo)量
pandas1.0以后的版本中引入了一個(gè)專(zhuān)門(mén)表示缺失值的標(biāo)量pd.NA,它代表空整數(shù)、空布爾值、空字符,這個(gè)功能目前處于實(shí)驗(yàn)階段。
開(kāi)發(fā)者也注意到了這點(diǎn),對(duì)于不同數(shù)據(jù)類(lèi)型采取不同的缺失值表示會(huì)很亂。pd.NA就是為了統(tǒng)一而存在的。pd.NA的目標(biāo)是提供一個(gè)缺失值指示器,可以在各種數(shù)據(jù)類(lèi)型中一致使用(而不是np.nan、None或者NaT分情況使用)。
s_new?=?pd.Series([1,?2],?dtype="Int64") s_new >>?0???1 ???1???2 ???dtype:?Int64 ----------------- s_new[1]?=?pd.NaT s_new >>?0????1 ???1??<NA> ???dtype:?Int64
同理,對(duì)于布爾型、字符型一樣不會(huì)改變?cè)袛?shù)據(jù)類(lèi)型,這樣就解決了原來(lái)動(dòng)不動(dòng)就變成object
類(lèi)型的麻煩了。
下面是pd.NA的一些常用算術(shù)運(yùn)算和比較運(yùn)算的示例:
#####?算術(shù)運(yùn)算 #?加法 pd.NA?+?1 >>?<NA> ----------- #?乘法 "a"?*?pd.NA >>?<NA> ----------- #?以下兩種其中結(jié)果為1 pd.NA?**?0 >>?1 ----------- 1?**?pd.NA >>?1 #####?比較運(yùn)算 pd.NA?==?pd.NA >>?<NA> ----------- pd.NA?<?2.5 >>?<NA> ----------- np.log(pd.NA) >>?<NA> ----------- np.add(pd.NA,?1) >>?<NA>
二、缺失值判斷
了解了缺失值的幾種形式后,我們要知道如何判斷缺失值。對(duì)于一個(gè)dataframe
而言,判斷缺失的主要方法就是isnull()
或者isna()
,這兩個(gè)方法會(huì)直接返回True
和False
的布爾值??梢允菍?duì)整個(gè)dataframe
或者某個(gè)列。
df?=?pd.DataFrame({ ??????'A':['a1','a1','a2','a3'], ??????'B':['b1',None,'b2','b3'], ??????'C':[1,2,3,4], ??????'D':[5,None,9,10]}) #?將無(wú)窮設(shè)置為缺失值?????? pd.options.mode.use_inf_as_na?=?True
1、對(duì)整個(gè)dataframe判斷缺失
df.isnull() >>?A?B?C?D 0?False?False?False?False 1?False?True?False?True 2?False?False?False?False 3?False?False?False?False
2、對(duì)某個(gè)列判斷缺失
df['C'].isnull() >>?0????False ???1????False ???2????False ???3????False Name:?C,?dtype:?bool
如果想取非缺失可以用notna()
,使用方法是一樣的,結(jié)果相反。
三、缺失值統(tǒng)計(jì)
1、列缺失
一般我們會(huì)對(duì)一個(gè)dataframe
的列進(jìn)行缺失統(tǒng)計(jì),查看每個(gè)列有多少缺失,如果缺失率過(guò)高再進(jìn)行刪除或者插值等操作。那么直接在上面的isnull()
返回的結(jié)果上直接應(yīng)用.sum()
即可,axis
默認(rèn)等于0,0是列,1是行。
##?列缺失統(tǒng)計(jì) isnull().sum(axis=0)
2、行缺失
但是很多情況下,我們也需要對(duì)行進(jìn)行缺失值判斷。比如一行數(shù)據(jù)可能一個(gè)值都沒(méi)有,如果這個(gè)樣本進(jìn)入模型,會(huì)造成很大的干擾。因此,行列兩個(gè)缺失率通常都要查看并統(tǒng)計(jì)。
操作很簡(jiǎn)單,只需要在sum()
中設(shè)置axis=1
即可。
##?行缺失統(tǒng)計(jì) isnull().sum(axis=1)
3、缺失率
有時(shí)我不僅想要知道缺失的數(shù)量,我更想知道缺失的比例,即缺失率。正??赡軙?huì)想到用上面求得數(shù)值再比上總行數(shù)。但其實(shí)這里有個(gè)小技巧可以一步就實(shí)現(xiàn)。
##?缺失率 df.isnull().sum(axis=0)/df.shape[0] ##?缺失率(一步到位) isnull().mean()
四、缺失值篩選
篩選需要loc配合完成,對(duì)于行和列的缺失篩選如下:
#?篩選有缺失值的行 df.loc[df.isnull().any(1)] >>?A?B?C?D 1?a1?None?2?NaN ----------------- #?篩選有缺失值的列 df.loc[:,df.isnull().any()] >>?B?D 0?b1?5.0 1?None?NaN 2?b2?9.0 3?b3?10.0
如果要查詢沒(méi)有缺失值的行和列,可以對(duì)表達(dá)式用取反~
操作:
df.loc[~(df.isnull().any(1))] >>?A?B?C?D 0?a1?b1?1?5.0 2?a2?b2?3?9.0 3?a3?b3?4?10.0
上面使用了any
判斷只要有缺失就進(jìn)行篩選,也可以用all
判斷是否全部缺失,同樣可以對(duì)行里進(jìn)行判斷,如果整列或者整行都是缺失值,那么這個(gè)變量或者樣本就失去了分析的意義,可以考慮刪除。
五、缺失值填充
一般我們對(duì)缺失值有兩種處理方法,一種是直接刪除,另外一種是保留并填充。下面先介紹填充的方法fillna
。
#?將dataframe所有缺失值填充為0 df.fillna(0) >>?A?B?C?D 0?a1?b1?1?5.0 1?a1?0?2?0.0 2?a2?b2?3?9.0 3?a3?b3?4?10.0 -------------- #?將D列缺失值填充為-999 df.D.fillna('-999') >>?0???????5 ???1????-999 ???2???????9 ???3??????10 Name:?D,?dtype:?object
方法很簡(jiǎn)單,但使用時(shí)需要注意一些參數(shù)。
inplace:可以設(shè)置
fillna(0, inplace=True)
來(lái)讓填充生效,原dataFrame被填充。methond:可以設(shè)置
methond
方法來(lái)實(shí)現(xiàn)向前或者向后填充,pad/ffill
為向前填充,bfill/backfill
為向后填充,比如df.fillna(methond='ffill')
,也可以簡(jiǎn)寫(xiě)為df.ffill()
。
df.ffill() >>?A?B?C?D 0?a1?b1?1?5.0 1?a1?b1?2?5.0 2?a2?b2?3?9.0 3?a3?b3?4?10.0
原缺失值都會(huì)按照前一個(gè)值來(lái)填充(B列1行,D列1行)。
除了用前后值來(lái)填充,也可以用整個(gè)列的均值來(lái)填充,比如對(duì)D列的其它非缺失值的平均值8來(lái)填充缺失值。
df.D.fillna(df.D.mean()) >>?0?????5.0 ???1?????8.0 ???2?????9.0 ???3????10.0 Name:?D,?dtype:?float64
六、缺失值刪除
刪除缺失值也非情況,比如是全刪除還是刪除比較高缺失率,這個(gè)要看自己的容忍程度,真實(shí)的數(shù)據(jù)必然會(huì)存在缺失的,這個(gè)無(wú)法避免。而且缺失在某些情況下也代表了一定的含義,要視情況而定。
1、全部直接刪除
#?全部直接刪除 df.dropna() >>?A?B?C?D 0?a1?b1?1?5.0 2?a2?b2?3?9.0 3?a3?b3?4?10.0
2、行缺失刪除
#?行缺失刪除 df.dropna(axis=0) >>?A?B?C?D 0?a1?b1?1?5.0 2?a2?b2?3?9.0 3?a3?b3?4?10.0
3、列缺失刪除
#?列缺失刪除 df.dropna(axis=1) >>?A?C 0?a1?1 1?a1?2 2?a2?3 3?a3?4 ------------- #?刪除指定列范圍內(nèi)的缺失,因?yàn)镃列無(wú)缺失,所以最后沒(méi)有變化 df.dropna(subset=['C']) >>?A?B?C?D 0?a1?b1?1?5.0 1?a1?None?2?NaN 2?a2?b2?3?9.0 3?a3?b3?4?10.0
4、按缺失率刪除
這個(gè)可以考慮用篩選的方法來(lái)實(shí)現(xiàn),比如要?jiǎng)h除列缺失大于0.1的(即篩選小于0.1的)。
df.loc[:,df.isnull().mean(axis=0)?<?0.1] >>?A?C 0?a1?1 1?a1?2 2?a2?3 3?a3?4 ------------- #?刪除行缺失大于0.1的 df.loc[df.isnull().mean(axis=1)?<?0.1] >>?A?B?C?D 0?a1?b1?1?5.0 2?a2?b2?3?9.0 3?a3?b3?4?10.0
七、缺失值參與計(jì)算
如果不對(duì)缺失值處理,那么缺失值會(huì)按照什么邏輯進(jìn)行計(jì)算呢?
下面我們一起看一下各種運(yùn)算下缺失值的參與邏輯。
1、加法
df >>A?B?C?D 0?a1?b1?1?5.0 1?a1?None?2?NaN 2?a2?b2?3?9.0 3?a3?b3?4?10.0 --------------- #?對(duì)所有列求和 df.sum() >>?A????a1a1a2a3 ???C??????????10 ???D??????????24
可以看到,加法是會(huì)忽略缺失值的。
2、累加
#?對(duì)D列進(jìn)行累加 df.D.cumsum() >>?0?????5.0 ???1?????NaN ???2????14.0 ???3????24.0 Name:?D,?dtype:?float64 --------------- df.D.cumsum(skipna=False) >>?0????5.0 ???1????NaN ???2????NaN ???3????NaN Name:?D,?dtype:?float64
cumsum
累加會(huì)忽略NA,但值會(huì)保留在列中,可以使用skipna=False
跳過(guò)有缺失值的計(jì)算并返回缺失值。
3、計(jì)數(shù)
#?對(duì)列計(jì)數(shù) df.count() >>?A????4 ???B????3 ???C????4 ???D????3 dtype:?int64
缺失值不進(jìn)入計(jì)數(shù)范圍里。
4、聚合分組
df.groupby('B').sum() >>?C?D B?? b1?1?5.0 b2?3?9.0 b3?4?10.0 --------------- df.groupby('B',dropna=False).sum() >>?C?D B?? b1?1?5.0 b2?3?9.0 b3?4?10.0 NaN?2?0.0
聚合時(shí)會(huì)默認(rèn)忽略缺失值,如果要缺失值計(jì)入到分組里,可以設(shè)置dropna=False
。這個(gè)用法和其它比如value_counts
是一樣的,有的時(shí)候需要看缺失值的數(shù)量。
五、源碼
所有數(shù)據(jù)和代碼可在我的GitHub
獲取:
https://github.com/xiaoyusmd/PythonDataScience
到此這篇關(guān)于詳解pandas中缺失數(shù)據(jù)處理的函數(shù)的文章就介紹到這了,更多相關(guān)pandas缺失數(shù)據(jù)處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python OpenCV學(xué)習(xí)之圖像濾波詳解
圖像濾波的作用簡(jiǎn)單來(lái)說(shuō)就是將一副圖像通過(guò)濾波器得到另一幅圖像;明確一個(gè)概念,濾波器又被稱(chēng)為卷積核,濾波的過(guò)程又被稱(chēng)為卷積;實(shí)際上深度學(xué)習(xí)就是訓(xùn)練許多適應(yīng)任務(wù)的濾波器,本質(zhì)上就是得到最佳的參數(shù)。下面來(lái)跟隨小編一起深入了解一下圖像濾波吧2022-01-01Kwargs傳遞給Python 中的另一個(gè)函數(shù)實(shí)現(xiàn)方法
Python 列出了可以傳遞給程序中的函數(shù)的兩種類(lèi)型的參數(shù), 非關(guān)鍵字參數(shù)**args和關(guān)鍵字參數(shù) **kwargs ,在本文中,我們將討論如何使用關(guān)鍵字參數(shù)及如何將關(guān)鍵字參數(shù)傳遞給另一個(gè)函數(shù),感興趣的朋友跟隨小編一起看看吧2023-08-08Python學(xué)習(xí)之魔法函數(shù)(filter,map,reduce)詳解
這篇文章我們將來(lái)學(xué)習(xí)一下,Python中的三個(gè)高級(jí)函數(shù):filter()、map()、reduce(),這三個(gè)函數(shù)也被稱(chēng)為魔法函數(shù),感興趣的小伙伴可以了解一下2022-04-04Python Vaex實(shí)現(xiàn)快速分析100G大數(shù)據(jù)量
Vaex是一個(gè)開(kāi)源的DataFrame庫(kù),它可以對(duì)表格數(shù)據(jù)集進(jìn)行可視化、探索、分析,甚至機(jī)器學(xué)習(xí),這些數(shù)據(jù)集和你的硬盤(pán)驅(qū)動(dòng)器一樣大。本文就來(lái)聊聊如何利用Vaex實(shí)現(xiàn)快速分析100G大數(shù)據(jù)量,需要的可以參考一下2023-03-03Python Dask庫(kù)處理大規(guī)模數(shù)據(jù)集的強(qiáng)大功能實(shí)戰(zhàn)
Dask是一個(gè)靈活、開(kāi)源的Python庫(kù),專(zhuān)為處理大規(guī)模數(shù)據(jù)集而設(shè)計(jì),與傳統(tǒng)的單機(jī)計(jì)算相比,Dask能夠在分布式系統(tǒng)上運(yùn)行,有效利用集群的計(jì)算資源,本文將深入介紹Dask的核心概念、功能和實(shí)際應(yīng)用,通過(guò)豐富的示例代碼展示其在大數(shù)據(jù)處理領(lǐng)域的強(qiáng)大能力2023-12-12用python生成與調(diào)用cntk模型代碼演示方法
今天小編就為大家分享一篇用python生成與調(diào)用cntk模型代碼演示方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08python爬蟲(chóng) urllib模塊發(fā)起post請(qǐng)求過(guò)程解析
這篇文章主要介紹了python爬蟲(chóng) urllib模塊發(fā)起post請(qǐng)求過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08