1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        【Python】pandas 缺失數(shù)據(jù)處理大全(附代碼)

        共 5764字,需瀏覽 12分鐘

         ·

        2022-01-19 16:20

        之前一直在分享pandas的一些騷操作:pandas騷操作,根據(jù)大家反映還不錯(cuò),但是很多技巧都混在了一起,沒有細(xì)致的分類,這樣不利于查找,也不成體系。

        利用閑暇之余將有關(guān)數(shù)據(jù)清洗、數(shù)據(jù)分析的一些技能再次進(jìn)行分類,里面也包含了我平時(shí)用到的一些小技巧,此次就從數(shù)據(jù)清洗缺失值處理走起,鏈接:pandas數(shù)據(jù)清洗,關(guān)注這個(gè)話題可第一時(shí)間看到更新。

        所有數(shù)據(jù)和代碼可在我的GitHub獲?。?/p>

        https://github.com/xiaoyusmd/PythonDataScience

        一、缺失值類型

        pandas中,缺失數(shù)據(jù)顯示為NaN。缺失值有3種表示方法,np.nan,none,pd.NA。

        1、np.nan

        缺失值有個(gè)特點(diǎn)(坑),它不等于任何值,連自己都不相等。如果用nan和任何其它值比較都會返回nan。

        np.nan?==?np.nan
        >>?False

        也正由于這個(gè)特點(diǎn),在數(shù)據(jù)集讀入以后,不論列是什么類型的數(shù)據(jù),默認(rèn)的缺失值全為np.nan

        因?yàn)?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(89, 89, 89);font-size: 13px;letter-spacing: 0.5px;">nan在Numpy中的類型是浮點(diǎn),因此整型列會轉(zhuǎn)為浮點(diǎn);而字符型由于無法轉(zhuǎn)化為浮點(diǎn)型,只能歸并為object類型('O'),原來是浮點(diǎn)型的則類型不變。

        type(np.nan)
        >>?float
        pd.Series([1,2,3]).dtype
        >>?dtype('int64')
        pd.Series([1,np.nan,3]).dtype
        >>?dtype('float64')

        初學(xué)者做數(shù)據(jù)處理遇見object類型會發(fā)懵,不知道這是個(gè)啥,明明是字符型,導(dǎo)入后就變了,其實(shí)是因?yàn)槿笔е祵?dǎo)致的。

        除此之外,還要介紹一種針對時(shí)間序列的缺失值,它是單獨(dú)存在的,用NaT表示,是pandas的內(nè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ù)值類型后,會自動變?yōu)?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(89, 89, 89);font-size: 13px;letter-spacing: 0.5px;">np.nan。

        type(pd.Series([1,None])[1])
        >>?numpy.float64

        只有當(dāng)傳入object類型時(shí)是不變的,因此可以認(rèn)為如果不是人工命名為None的話,它基本不會自動出現(xiàn)在pandas中,所以None大家基本也看不到。

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

        3、NA標(biāo)量

        pandas1.0以后的版本中引入了一個(gè)專門表示缺失值的標(biāo)量pd.NA,它代表空整數(shù)、空布爾值、空字符,這個(gè)功能目前處于實(shí)驗(yàn)階段。

        開發(fā)者也注意到了這點(diǎn),對于不同數(shù)據(jù)類型采取不同的缺失值表示會很亂。pd.NA就是為了統(tǒng)一而存在的。pd.NA的目標(biāo)是提供一個(gè)缺失值指示器,可以在各種數(shù)據(jù)類型中一致使用(而不是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??
        ???dtype:?Int64

        同理,對于布爾型、字符型一樣不會改變原有數(shù)據(jù)類型,這樣就解決了原來動不動就變成object類型的麻煩了。

        下面是pd.NA的一些常用算術(shù)運(yùn)算和比較運(yùn)算的示例:

        #####?算術(shù)運(yùn)算
        #?加法
        pd.NA?+?1
        >>?
        -----------
        #?乘法
        "a"?*?pd.NA
        >>?
        -----------
        #?以下兩種其中結(jié)果為1
        pd.NA?**?0
        >>?1
        -----------
        1?**?pd.NA
        >>?1

        #####?比較運(yùn)算
        pd.NA?==?pd.NA
        >>?
        -----------
        pd.NA?2.5
        >>?
        -----------
        np.log(pd.NA)
        >>?
        -----------
        np.add(pd.NA,?1)
        >>?

        二、缺失值判斷

        了解了缺失值的幾種形式后,我們要知道如何判斷缺失值。對于一個(gè)dataframe而言,判斷缺失的主要方法就是isnull()或者isna(),這兩個(gè)方法會直接返回TrueFalse的布爾值??梢允菍φ麄€(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]})
        #?將無窮設(shè)置為缺失值??????
        pd.options.mode.use_inf_as_na?=?True

        1、對整個(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、對某個(gè)列判斷缺失

        df['C'].isnull()
        >>?0????False
        ???1????False
        ???2????False
        ???3????False
        Name:?C,?dtype:?bool

        如果想取非缺失可以用notna(),使用方法是一樣的,結(jié)果相反。

        三、缺失值統(tǒng)計(jì)

        1、列缺失

        一般我們會對一個(gè)dataframe進(jìn)行缺失統(tǒng)計(jì),查看每個(gè)列有多少缺失,如果缺失率過高再進(jìn)行刪除或者插值等操作。那么直接在上面的isnull()返回的結(jié)果上直接應(yīng)用.sum()即可,axis默認(rèn)等于0,0是列,1是行。

        ##?列缺失統(tǒng)計(jì)
        isnull().sum(axis=0)

        2、行缺失

        但是很多情況下,我們也需要對進(jìn)行缺失值判斷。比如一行數(shù)據(jù)可能一個(gè)值都沒有,如果這個(gè)樣本進(jìn)入模型,會造成很大的干擾。因此,行列兩個(gè)缺失率通常都要查看并統(tǒng)計(jì)。

        操作很簡單,只需要在sum()中設(shè)置axis=1即可。

        ##?行缺失統(tǒng)計(jì)
        isnull().sum(axis=1)

        3、缺失率

        有時(shí)我不僅想要知道缺失的數(shù)量,我更想知道缺失的比例,即缺失率。正常可能會想到用上面求得數(shù)值再比上總行數(shù)。但其實(shí)這里有個(gè)小技巧可以一步就實(shí)現(xiàn)。

        ##?缺失率
        df.isnull().sum(axis=0)/df.shape[0]

        ##?缺失率(一步到位)
        isnull().mean()

        四、缺失值篩選

        篩選需要loc配合完成,對于行和列的缺失篩選如下:

        #?篩選有缺失值的行
        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

        如果要查詢沒有缺失值的行和列,可以對表達(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判斷是否全部缺失,同樣可以對行里進(jìn)行判斷,如果整列或者整行都是缺失值,那么這個(gè)變量或者樣本就失去了分析的意義,可以考慮刪除。

        五、缺失值填充

        一般我們對缺失值有兩種處理方法,一種是直接刪除,另外一種是保留并填充。下面先介紹填充的方法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

        方法很簡單,但使用時(shí)需要注意一些參數(shù)。

        • inplace:可以設(shè)置fillna(0, inplace=True)來讓填充生效,原dataFrame被填充。
        • methond:可以設(shè)置methond方法來實(shí)現(xiàn)向前或者向后填充,pad/ffill為向前填充,bfill/backfill為向后填充,比如df.fillna(methond='ffill'),也可以簡寫為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

        原缺失值都會按照前一個(gè)值來填充(B列1行,D列1行)。

        除了用前后值來填充,也可以用整個(gè)列的均值來填充,比如對D列的其它非缺失值的平均值8來填充缺失值。

        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ù)必然會存在缺失的,這個(gè)無法避免。而且缺失在某些情況下也代表了一定的含義,要視情況而定。

        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)镃列無缺失,所以最后沒有變化
        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è)可以考慮用篩選的方法來實(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ì)算

        如果不對缺失值處理,那么缺失值會按照什么邏輯進(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
        ---------------
        #?對所有列求和
        df.sum()
        >>?A????a1a1a2a3
        ???C??????????10
        ???D??????????24

        可以看到,加法是會忽略缺失值的。

        2、累加

        #?對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累加會忽略NA,但值會保留在列中,可以使用skipna=False跳過有缺失值的計(jì)算并返回缺失值。

        3、計(jì)數(shù)

        #?對列計(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í)會默認(rèn)忽略缺失值,如果要缺失值計(jì)入到分組里,可以設(shè)置dropna=False。這個(gè)用法和其它比如value_counts是一樣的,有的時(shí)候需要看缺失值的數(shù)量。

        以上就是所有關(guān)于缺失值的常用操作了,從理解缺失值的3種表現(xiàn)形式開始,到缺失值判斷、統(tǒng)計(jì)、處理、計(jì)算等。

        原創(chuàng)不易,歡迎點(diǎn)贊、在看支持。

        參考:

        [1]深入淺出pandas

        [2]https://mp.weixin.qq.com/s/Ool5T49RxYj-Os4DWzTeyQ


        往期精彩回顧




        瀏覽 47
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            男女生互操 | 爆操御姐| 亚洲深深色噜噜狠狠网站 | 黄色短视频网址在线播放 | a级情欲片在线观看 | 男人猛躁女人秘 91网站 | 大香蕉操逼网 | 91无码人妻一区二区成人AⅤ | 国产福利91精品一区 | 99精品这里只有免费视频 |