<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Pandas中的這3個函數(shù),沒想到竟成了我數(shù)據(jù)處理的主力

          共 4634字,需瀏覽 10分鐘

           ·

          2021-03-09 19:24



          導(dǎo)讀

          學Pandas有一年多了,用Pandas做數(shù)據(jù)分析也快一年了,常常在總結(jié)梳理一些Pandas中好用的方法。例如三個最愛函數(shù)計數(shù)、數(shù)據(jù)透視表、索引變換聚合統(tǒng)計以及時間序列等等,每一個都稱得上是認知的升華、實踐的結(jié)晶。今天,延承這一系列,再分享三個函數(shù),堪稱是個人日常在數(shù)據(jù)處理環(huán)節(jié)中應(yīng)用頻率較高的3個函數(shù):apply、map和applymap,其中apply是主角,map和applymap為贈送。

          d1f25b4a602332a5336371f7fd588659.webp

          數(shù)據(jù)處理環(huán)節(jié)無非就是各種數(shù)據(jù)清洗,除了常規(guī)的缺失值和重復(fù)值處理邏輯相對較為簡單,更為復(fù)雜的其實當屬異常值處理以及各種數(shù)據(jù)變換:例如類型轉(zhuǎn)換、簡單數(shù)值計算等等。在這一過程中,如何既能保證數(shù)據(jù)處理效率而又不失優(yōu)雅,Pandas中的這幾個函數(shù)堪稱理想的解決方案。


          為展示應(yīng)用這3個函數(shù)完成數(shù)據(jù)處理過程中的一些demo,這里以經(jīng)典的泰坦尼克號數(shù)據(jù)集為例。需要下載該數(shù)據(jù)集和文中示例源碼的可后臺回復(fù)關(guān)鍵字apply獲取下載方式。


          01 apply的方法論

          在學習apply具體應(yīng)用之前,有必要首先闡釋apply函數(shù)的方法論。apply英文原義是"應(yīng)用"的意思,作為編程語言中的函數(shù)名,似乎在很多種語言都有體現(xiàn),比如近日個人在學習Scala語言中apply被用作是伴生對象中自動創(chuàng)建對象的缺省實現(xiàn),如此重要的角色也可見apply這個函數(shù)的重要性。那么apply應(yīng)用在Pandas中,其核心功能其實可以概括為一句話:

          apply:我本身不處理數(shù)據(jù),我們只是數(shù)據(jù)的搬運工。


          說人話就是,apply自身是不帶有任何數(shù)據(jù)處理功能的,但可以用作是對其他數(shù)據(jù)處理方法的調(diào)度器,至于調(diào)度什么又為誰而調(diào)度呢?這是理解apply的兩個核心環(huán)節(jié):
          • 調(diào)度什么?調(diào)度的是apply函數(shù)接收的參數(shù),即apply接收一個數(shù)據(jù)處理函數(shù)為主要參數(shù),并將其應(yīng)用到相應(yīng)的數(shù)據(jù)上。所以調(diào)度什么取決于接收了什么樣的數(shù)據(jù)處理函數(shù);
          • 為誰調(diào)度?也就是apply接收的數(shù)據(jù)處理函數(shù),其作用對象是誰?或者說數(shù)據(jù)處理的粒度是什么?答案是數(shù)據(jù)處理的粒度包括了點線面三個層面:即可以是單個元素(標量,scalar),也可以是一行或一列(series),還可以是一個dataframe。


          當然,這些文字描述肯定還比較抽象,那么不妨直接進入正題:talk is cheap,show me the code!


          02 apply基本方法示例

          前面提到,理解apply核心在于明確兩個環(huán)節(jié):調(diào)度函數(shù)和作用對象。調(diào)度函數(shù)就是apply接收的參數(shù),既可以是Python內(nèi)置的函數(shù),也支持自定義函數(shù),只要符合指定的作用對象(即是標量還是series亦或一個dataframe)即可。而作用對象則取決于調(diào)用apply的對象類型,具體來說:

          • 一個Series對象調(diào)用apply時,數(shù)據(jù)處理函數(shù)作用于該Series的每個元素上,即作用對象是一個標量,實現(xiàn)從一個Series轉(zhuǎn)換到另一個Series;

          • 一個DataFrame對象調(diào)用apply時,數(shù)據(jù)處理函數(shù)作用于該DataFrame的每一行或者每一列上,即作用對象是一個Series,實現(xiàn)從一個DataFrame轉(zhuǎn)換到一個Series上;

          • 一個DataFrame對象經(jīng)過groupby分組后調(diào)用apply時,數(shù)據(jù)處理函數(shù)作用于groupby后的每個子dataframe上,即作用對象還是一個DataFrame(行是每個分組對應(yīng)的行;列字段少了groupby的相應(yīng)列),實現(xiàn)從一個DataFrame轉(zhuǎn)換到一個Series上。


          以泰坦尼克號數(shù)據(jù)集為例,這里分別舉幾個小例子。原始數(shù)據(jù)集如下:

          e7a4285370499c9d9c98d1706016867e.webp


          1. 應(yīng)用到Series的每個元素①將性別sex列轉(zhuǎn)化為0和1數(shù)值,其中female對應(yīng)0,male對應(yīng)1。應(yīng)用apply函數(shù)實現(xiàn)這一功能非常簡單:

          b52d9820ebf7601078dd93149a574a1e.webp


          其中,這里apply接收了一個lambda匿名函數(shù),通過一個簡單的if-else邏輯實現(xiàn)數(shù)據(jù)映射。該功能十分簡單,接收的函數(shù)也不帶任何其他參數(shù)。


          ②下面再來一個稍微復(fù)雜一點的案例,注意到年齡age列當前數(shù)據(jù)類型是小數(shù),需要將其轉(zhuǎn)換為整數(shù),同時還有0.9167這種過小的年齡,所以要求接受一個函數(shù),支持接受指定的最大和最小年齡限制,當數(shù)據(jù)中超出此年齡范圍的統(tǒng)一用截斷填充,同時由于原數(shù)據(jù)集中age列存在缺失值,還需首先進行缺失值填充。這里首先實現(xiàn)一個自定義函數(shù)用于實現(xiàn)指定的年齡處理功能:

          def get_age(age, max_age, min_age):    age = int(age)  # 轉(zhuǎn)換為整數(shù)    if age > max_age:        age = max_age    if age < min_age:        age = min_age    return age

          然后,直接對age列調(diào)用該函數(shù)即可,其中除了第一個參數(shù)age由調(diào)用該函數(shù)的series進行向量化填充外,另兩個參數(shù)需要指定,在apply中即通過args傳入。具體而言,實現(xiàn)如下:

          6f4d76556d372779d38e7eb721ce8cdd.webp


          2. 應(yīng)用到DataFrame的每個Series

          DataFrame是pandas中的核心數(shù)據(jù)結(jié)構(gòu),其每一行和每一列都是一個Series數(shù)據(jù)類型。那么應(yīng)用apply到一個DataFrame的每個Series,自然存在一個問題是應(yīng)用到行還是列的問題,所以一個DataFrame調(diào)用apply函數(shù)時需要指定一個axis參數(shù),其中axis=0對應(yīng)行方向的處理,即對每列應(yīng)用apply接收函數(shù);axis=1對應(yīng)列方向處理,即對每行應(yīng)用接收函數(shù)。默認為axis=0。這里仍然舉兩個小例子:


          ①取所有數(shù)值列的數(shù)據(jù)最大值。當然,這個處理其實可以直接調(diào)用max函數(shù),但這里為了演示apply應(yīng)用,所以不妨照此嘗試:

          602cdbdde029aa908b94dcdf02c349fc.webp

          上述apply函數(shù)完成了對四個數(shù)值列求取最大值,其中缺省axis參數(shù)為0,對應(yīng)行方向處理,即對每一列數(shù)據(jù)求最大值。


          ②然后來一個按行方向處理的例子,例如根據(jù)性別和年齡,區(qū)分4類人群:即女孩、成年女子、男孩、成年男子,其中年齡以18歲為界值進行區(qū)分。首先給出人群劃分的函數(shù)實現(xiàn):

          def cat_person(sr):    if sr['sex_num'] == 0:        if sr['age_num'] < 18:            return '女孩'        else:            return '成年女子'    else:        if sr['age_num'] < 18:            return '男孩'        else:            return '成年男子'

          基于此,用apply簡單調(diào)用即可,其中axis=1設(shè)置apply的作用方向為按列方向,即對每行進行處理。其中每行都相當于一個帶有age和sex等信息的Series,通過cat_person函數(shù)進行提取判斷,即實現(xiàn)了人群的劃分:

          c013e22024d58572dd6ca8bde715c8ae.webp


          3. 應(yīng)用到DataFrame groupby后的每個分組DataFrame實際上,個人一直覺得這是一個非常有效的用法,相較于原生的groupby,通過配套使用goupby+apply兩個函數(shù),實現(xiàn)更為個性化的聚合統(tǒng)計功能。例如,這里我們希望統(tǒng)計不同艙位等級內(nèi)的"生存年齡比"(僅為配合舉例而隨意定義的指標,無實際含義),定義為各艙位等級內(nèi)生存人員的年齡之和與所有人員年齡之和的比值。為實現(xiàn)這一數(shù)據(jù)統(tǒng)計,則首先應(yīng)以艙位等級作為分組字段進行分組,而后對每個分組內(nèi)的數(shù)據(jù)進行聚合統(tǒng)計,示例代碼如下:

          77234c7fc20c75c8ffa4d22d01e2e7d5.webp


          其中apply接收一個lambda匿名函數(shù),該匿名函數(shù)接收一個dataframe為參數(shù)(該dataframe中不含pclass列),并提取survived列和age_num列參與計算。最后得到每個艙位等級的一個統(tǒng)計指標結(jié)果,返回類型是一個Series對象。


          這里,再補充一個前期分享過的一片推文:Pandas用的6不6,來試試這道題就能看出來,實際上也是實現(xiàn)了相同的分組聚合統(tǒng)計功能。


          以上,可以梳理apply函數(shù)的執(zhí)行流程:首先明確調(diào)用apply的數(shù)據(jù)結(jié)構(gòu)類型,是Series還是DataFrame,如果是DataFrame還需進一步確定是直接調(diào)用apply還是經(jīng)過groupby分組之后調(diào)用,其中前者對應(yīng)apply的接收函數(shù)處理一行或一列,后者對應(yīng)接收函數(shù)處理每個分組對應(yīng)的子DataFrame,最后根據(jù)作用對象類型設(shè)計相應(yīng)的接收函數(shù),從而完成個性化的數(shù)據(jù)處理。


          03 apply的兩個兄弟

          前面介紹了apply的三種應(yīng)用場景,作用對象分別對應(yīng)元素、Series以及DataFrame,可以說功能已經(jīng)非常強大了。除了apply之外,pandas其實還提供了兩個功能極為相近的函數(shù):map和applymap,不過相較于功能強大的apply來說,二者功能則相對局限。具體而言,二者分別實現(xiàn)功能如下:


          1.map。在Python中提到map關(guān)鍵詞,個人首先聯(lián)想到的是兩個場景:①一種數(shù)據(jù)結(jié)構(gòu),即字典或者叫映射,通過鍵值對的方式組織數(shù)據(jù),在Python中叫dict;②Python的一個內(nèi)置函數(shù)叫map,實現(xiàn)數(shù)據(jù)按照一定規(guī)則完成映射的過程。而在Pandas框架中,這兩種含義都有所體現(xiàn):對一個Series對象的每個元素實現(xiàn)字典映射或者函數(shù)變換,其中后者與apply應(yīng)用于Series的用法完全一致,而前者則僅僅是簡單將函數(shù)參數(shù)替換為字典變量即可。仍以替換性別一列為0/1數(shù)值為例,應(yīng)用map函數(shù)的實現(xiàn)方式為:

          23e9fd0dcc6d3a0a7d51ecf029567e82.webp


          雖然map對于Series元素級的變換提供了兩種數(shù)據(jù)轉(zhuǎn)換方式,但卻僅能用于Series,而無法應(yīng)用到DataFrame上。但與此同時,map相較于apply又在另一個方面具有獨特應(yīng)用,即對于索引列這種特殊的Series只能應(yīng)用map,而無法應(yīng)用apply。

          9b1ecd7de8aaf7078fa6fd78f4eba80e.webp


          2.applymap。從名字上可以看出,這好像是個apply函數(shù)與map函數(shù)的混合體,實際上也確實有這方面的味道:即applymap綜合了apply可以應(yīng)用到DataFrame和map僅能應(yīng)用到元素級進行變換的雙重特性,所以applymap是將接收函數(shù)應(yīng)用于DataFrame的每個元素,以實現(xiàn)相應(yīng)的變換。
          從某種角度來講,這種變換得以實施的前提是該DataFrame的各列元素具有相同的數(shù)據(jù)類型和相近的業(yè)務(wù)含義,否則運用相同的數(shù)據(jù)變換很難保證實際效果。

          假設(shè)需要獲取DataFrame中各個元素的數(shù)據(jù)類型,則應(yīng)用applymap實現(xiàn)如下:

          04b9cc73d2571db6740a6b80ada60f02.webp


          04 小結(jié)
          • apply、map和applymap常用于實現(xiàn)Pandas中的數(shù)據(jù)變換,通過接收一個函數(shù)實現(xiàn)特定的變換規(guī)則;

          • apply功能最為強大,可應(yīng)用于Series、DataFrame以及DataFrame分組后的group DataFrame,分別實現(xiàn)元素級、Series級以及DataFrame級別的數(shù)據(jù)變換;

          • map僅可作用于Series實現(xiàn)元素級的變換,既可以接收一個字典完成變化也可接收特定的函數(shù),而且不僅可作用于普通的Series類型,也可用于索引列的變換,而索引列的變換是apply所不能應(yīng)用的;

          • applymap僅可用于DataFrame,接收一個函數(shù)實現(xiàn)對所有數(shù)據(jù)實現(xiàn)元素級的變換



          7085535ee80e041620504c40ccf83bf3.webp


          6e1af135255d00f5abc48d4d327811b2.webp

          Python自動化辦公之Word,全網(wǎng)最全看這一篇就夠了


          915ae3c2ea576fa4cfae897495a504ab.webp

          5個無聊Python程序,用Python整蠱你的朋友們吧


          瀏覽 43
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  99精品视频免费观看 | 肏逼网站自拍 | 亚洲日本一级片 | 午夜美女福利视频 | 苍井空精毛片精品久久久 |