自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

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

[[378227]]

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

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

01 apply的方法論

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

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

說(shuō)人話就是,apply自身是不帶有任何數(shù)據(jù)處理功能的,但可以用作是對(duì)其他數(shù)據(jù)處理方法的調(diào)度器,至于調(diào)度什么又為誰(shuí)而調(diào)度呢?這是理解apply的兩個(gè)核心環(huán)節(jié):

  • 調(diào)度什么?調(diào)度的是apply函數(shù)接收的參數(shù),即apply接收一個(gè)數(shù)據(jù)處理函數(shù)為主要參數(shù),并將其應(yīng)用到相應(yīng)的數(shù)據(jù)上。所以調(diào)度什么取決于接收了什么樣的數(shù)據(jù)處理函數(shù);
  • 為誰(shuí)調(diào)度?也就是apply接收的數(shù)據(jù)處理函數(shù),其作用對(duì)象是誰(shuí)?或者說(shuō)數(shù)據(jù)處理的粒度是什么?答案是數(shù)據(jù)處理的粒度包括了點(diǎn)線面三個(gè)層面:即可以是單個(gè)元素(標(biāo)量,scalar),也可以是一行或一列(series),還可以是一個(gè)dataframe。

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

02 apply基本方法

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

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

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

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

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

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

  1. def get_age(age, max_age, min_age): 
  2.     age = int(age)  # 轉(zhuǎn)換為整數(shù) 
  3.     if age > max_age: 
  4.         age = max_age 
  5.     if age < min_age: 
  6.         age = min_age 
  7.     return age 

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

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

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

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

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

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

  1. def cat_person(sr): 
  2.     if sr['sex_num'] == 0: 
  3.         if sr['age_num'] < 18: 
  4.             return '女孩' 
  5.         else
  6.             return '成年女子' 
  7.     else
  8.         if sr['age_num'] < 18: 
  9.             return '男孩' 
  10.         else
  11.             return '成年男子' 

基于此,用apply簡(jiǎn)單調(diào)用即可,其中axis=1設(shè)置apply的作用方向?yàn)榘戳蟹较?,即?duì)每行進(jìn)行處理。其中每行都相當(dāng)于一個(gè)帶有age和sex等信息的Series,通過cat_person函數(shù)進(jìn)行提取判斷,即實(shí)現(xiàn)了人群的劃分:

3. 應(yīng)用到DataFrame groupby后的每個(gè)分組DataFrame

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

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

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

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

03 apply的兩個(gè)兄弟

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

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

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

2.applymap。從名字上可以看出,這好像是個(gè)apply函數(shù)與map函數(shù)的混合體,實(shí)際上也確實(shí)有這方面的味道:即applymap綜合了apply可以應(yīng)用到DataFrame和map僅能應(yīng)用到元素級(jí)進(jìn)行變換的雙重特性,所以applymap是將接收函數(shù)應(yīng)用于DataFrame的每個(gè)元素,以實(shí)現(xiàn)相應(yīng)的變換。

從某種角度來(lái)講,這種變換得以實(shí)施的前提是該DataFrame的各列元素具有相同的數(shù)據(jù)類型和相近的業(yè)務(wù)含義,否則運(yùn)用相同的數(shù)據(jù)變換很難保證實(shí)際效果。

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

04 小結(jié)

  • apply、map和applymap常用于實(shí)現(xiàn)Pandas中的數(shù)據(jù)變換,通過接收一個(gè)函數(shù)實(shí)現(xiàn)特定的變換規(guī)則;
  • apply功能最為強(qiáng)大,可應(yīng)用于Series、DataFrame以及DataFrame分組后的group DataFrame,分別實(shí)現(xiàn)元素級(jí)、Series級(jí)以及DataFrame級(jí)別的數(shù)據(jù)變換;
  • map僅可作用于Series實(shí)現(xiàn)元素級(jí)的變換,既可以接收一個(gè)字典完成變化也可接收特定的函數(shù),而且不僅可作用于普通的Series類型,也可用于索引列的變換,而索引列的變換是apply所不能應(yīng)用的;
  • applymap僅可用于DataFrame,接收一個(gè)函數(shù)實(shí)現(xiàn)對(duì)所有數(shù)據(jù)實(shí)現(xiàn)元素級(jí)的變換

 

 

責(zé)任編輯:未麗燕 來(lái)源: 小數(shù)志
相關(guān)推薦

2018-01-26 23:23:23

JDBC MySQL數(shù)據(jù)庫(kù)

2018-12-26 09:44:02

分布式緩存本地緩存

2024-01-04 12:33:17

ChatGPTAI視頻

2021-01-27 18:13:35

日志nginx信息

2023-12-26 15:10:00

處理二進(jìn)制文件

2022-03-21 08:55:53

RocketMQ客戶端過濾機(jī)制

2019-03-08 10:08:41

網(wǎng)絡(luò)程序猿代碼

2017-12-26 15:41:26

2023-01-17 17:54:47

MQ數(shù)據(jù)丟失

2019-04-28 14:14:48

爬蟲網(wǎng)絡(luò)特價(jià)機(jī)票

2021-03-18 09:06:17

函數(shù)MainJava

2018-10-22 15:29:50

2023-09-07 06:48:38

Intel顯卡AMD

2022-11-02 07:46:31

GoFrameGcache緩存

2020-12-31 06:12:38

Siri Windows電腦

2023-09-08 06:39:33

NVIDIA顯卡行業(yè)

2025-03-11 01:28:16

2012-12-28 13:47:36

Raspberry PGeek

2017-02-09 17:00:00

iOSSwiftKVC

2022-01-05 17:13:28

監(jiān)控HTTPS網(wǎng)站
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)