分享Pandas庫(kù)中的一些寶藏函數(shù)transform()
Pandas函數(shù)的核心功能是,既計(jì)算了統(tǒng)計(jì)值,又保留了明細(xì)數(shù)據(jù)。為了更好地理解transform和agg的不同,下面從實(shí)際的應(yīng)用場(chǎng)景出發(fā)進(jìn)行對(duì)比。
aggregation會(huì)返回?cái)?shù)據(jù)的縮減版本,而transformation能返回完整數(shù)據(jù)的某一變換版本供我們重組。這樣的transformation,輸出的形狀和輸入一致。一個(gè)常見(jiàn)的例子是通過(guò)減去分組平均值來(lái)居中數(shù)據(jù)。
#數(shù)據(jù)構(gòu)造 data = pd.DataFrame( {"company":['百度', '阿里', '百度', '阿里', '百度', '騰訊', '騰訊', '阿里', '騰訊', '阿里'], "salary":[43000, 24000, 40000, 39000, 8000, 47000, 25000, 16000, 21000, 38000], "age":[25, 34, 49, 42, 28, 23, 45, 21, 34, 29]}) data company salary age 0百度4300025 1阿里2400034 2百度4000049 3阿里3900042 4百度 800028 5騰訊4700023 6騰訊2500045 7阿里1600021 8騰訊2100034 9阿里3800029
1、transform作用于Series
1)單個(gè)變換函數(shù)
當(dāng)transform作用于單列Series時(shí)較為簡(jiǎn)單 ,對(duì)salary列進(jìn)行transform變換我們可以傳入任意的非聚合類函數(shù),比如對(duì)工資列對(duì)數(shù)化
import pandas as pd import numpy as np # 對(duì)工資對(duì)數(shù)化 data['salary'].transform(np.log) 0 10.668955 1 10.085809 2 10.596635 3 10.571317 4 8.987197 5 10.757903 6 10.126631 7 9.680344 8 9.952278 9 10.545341 Name: salary, dtype: float64
除了內(nèi)置函數(shù),還可以傳入lambda函數(shù)
# lambda函數(shù) data['salary'].transform(lambda s: s+1) 0 43001 1 24001 2 40001 3 39001 4 8001 5 47001 6 25001 7 16001 8 21001 9 38001 Name: salary, dtype: int64
2)多個(gè)變換函數(shù)
也可以傳入包含多個(gè)變換函數(shù)的列表來(lái)一口氣計(jì)算出多列結(jié)果:
data['salary'].transform([np.log, lambda s: s+1, np.sqrt]) log <lambda> sqrt 0 10.668955 43001 207.364414 1 10.085809 24001 154.919334 2 10.596635 40001 200.000000 3 10.571317 39001 197.484177 48.987197800189.442719 5 10.757903 47001 216.794834 6 10.126631 25001 158.113883 79.680344 16001 126.491106 89.952278 21001 144.913767 9 10.545341 38001 194.935887
而又因?yàn)閠ransform傳入的函數(shù),在執(zhí)行運(yùn)算時(shí)接收的輸入?yún)?shù)是對(duì)應(yīng)的整列數(shù)據(jù),所以我們可以利用這個(gè)特點(diǎn)實(shí)現(xiàn)諸如數(shù)據(jù)標(biāo)準(zhǔn)化、歸一化等需要依賴樣本整體統(tǒng)計(jì)特征的變換過(guò)程:
# 利用transform進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化 data['salary'].transform(lambda s: (s - s.mean()) / s.std()) 0 0.991038 1-0.468630 2 0.760564 3 0.683739 4-1.697825 5 1.298337 6-0.391806 7-1.083228 8-0.699104 9 0.606915 Name: salary, dtype: float64
2、 transform作用于DataFrame
當(dāng)transform作用于整個(gè)DataFrame時(shí),實(shí)際上就是將傳入的所有變換函數(shù)作用到每一列中:
data.loc[:,'salary':'age'].transform(lambda s:(s-s.mean()) /s.std()) salary age 0 0.991038 -0.832050 1 -0.468630 0.104006 2 0.760564 1.664101 3 0.683739 0.936057 4 -1.697825 -0.520031 5 1.298337 -1.040063 6 -0.391806 1.248075 7 -1.083228 -1.248075 8 -0.699104 0.104006 9 0.606915 -0.416025
而當(dāng)傳入多個(gè)變換函數(shù)時(shí),對(duì)應(yīng)的返回結(jié)果格式類似agg中的機(jī)制,會(huì)生成MultiIndex格式的字段名
data.loc[:, 'salary': 'age'].transform([np.log, lambda s: s+1]) salary age log <lambda> log <lambda> 0 10.668955 43001 3.218876 26 1 10.085809 24001 3.526361 35 2 10.596635 40001 3.891820 50 3 10.571317 39001 3.737670 43 48.987197 8001 3.332205 29 5 10.757903 47001 3.135494 24 6 10.126631 25001 3.806662 46 79.680344 16001 3.044522 22 89.952278 21001 3.526361 35 9 10.545341 38001 3.367296 30
而且由于作用的是DataFrame,還可以利用字典以鍵值對(duì)的形式,一口氣為每一列配置單個(gè)或多個(gè)變換函數(shù):
(data.loc[:, 'salary': 'age'] .transform({'age': lambda s: (s - s.mean()) / s.std(), 'salary': [np.log, np.sqrt]})) age salary <lambda> log sqrt 0 -0.832050 10.668955 207.364414 1 0.104006 10.085809 154.919334 2 1.664101 10.596635 200.000000 3 0.936057 10.571317 197.484177 4 -0.5200318.98719789.442719 5 -1.040063 10.757903 216.794834 6 1.248075 10.126631 158.113883 7 -1.2480759.680344 126.491106 8 0.1040069.952278 144.913767 9 -0.416025 10.545341 194.935887
3、transform作用于groupby分組后
在原來(lái)的數(shù)據(jù)中,我們知道了如何求不同公司的平均薪水,假如需要在原數(shù)據(jù)集中新增一列salary_mean,代表該公司的平均薪水,該怎么實(shí)現(xiàn)呢?
data['salary_mean'] = data.groupby('company')[['salary']].transform('mean') data company salary agesalary_mean 0百度4300025 30333.333333 1阿里2400034 29250.000000 2百度4000049 30333.333333 3阿里3900042 29250.000000 4百度 800028 30333.333333 5騰訊4700023 31000.000000 6騰訊2500045 31000.000000 7阿里1600021 29250.000000 8騰訊2100034 31000.000000 9阿里3800029 29250.000000
通過(guò)上面的數(shù)據(jù)可以看出,利用transform輸出既得到了統(tǒng)計(jì)數(shù)據(jù),形狀也沒(méi)有變化。
當(dāng)然,也可對(duì)多個(gè)數(shù)據(jù)列進(jìn)行計(jì)算
data.groupby('company')[['salary', 'age']].transform('mean') salaryage 0 30333.333333 34.0 1 29250.000000 31.5 2 30333.333333 34.0 3 29250.000000 31.5 4 30333.333333 34.0 5 31000.000000 34.0 6 31000.000000 34.0 7 29250.000000 31.5 8 31000.000000 34.0 9 29250.000000 31.5
我們也可以用map函數(shù)實(shí)現(xiàn)類似的功能,但是稍微復(fù)雜點(diǎn),但是有助于我們理解transform的含義。
avg_dict = data.groupby('company')['salary'].mean().to_dict() avg_dict#得到了一個(gè)平均工資的字典 {'百度': 30333.333333333332, '騰訊': 31000.0, '阿里': 29250.0} #利用map函數(shù),將得到的字典映射到對(duì)應(yīng)的列 data['salary_mean'] = data['company'].map(avg_dict) data company salary agesalary_mean 0百度4300025 30333.333333 1阿里2400034 29250.000000 2百度4000049 30333.333333 3阿里3900042 29250.000000 4百度 800028 30333.333333 5騰訊4700023 31000.000000 6騰訊2500045 31000.000000 7阿里1600021 29250.000000 8騰訊2100034 31000.000000 9阿里3800029 29250.000000
以圖解的方式來(lái)看看進(jìn)行g(shù)roupby后transform的實(shí)現(xiàn)過(guò)程(公司列包含ABC,salary列為每個(gè)員工的工資明細(xì)):
上圖中的大方框是transform和agg 所不一樣的地方,對(duì)agg而言,會(huì)計(jì)算并聚合得到 A,B,C 公司對(duì)應(yīng)的均值并直接返回,每個(gè)公司一條數(shù)據(jù),但對(duì)transform而言,則會(huì)對(duì)每一條數(shù)據(jù)求得相應(yīng)的結(jié)果,同一組內(nèi)的樣本會(huì)有相同的值,組內(nèi)求完均值后會(huì)按照原索引的順序返回結(jié)果。
以上就是分享Pandas中的一些寶藏函數(shù)transform()的詳細(xì)內(nèi)容,更多關(guān)于Pandas函數(shù)transform()的資料請(qǐng)關(guān)注本站其它相關(guān)文章!
版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。