譯:理解pandas中的tansform函數(shù)

原文鏈接:Understanding the Transform Function in Pandas

transform示例

引言

pandas庫擁有著豐富的方法操控數(shù)據(jù),這是他的一大優(yōu)勢狞换,但有時候污呼,因為龐大的功能裕坊,你總會碰到一些不了解功能和用法的函數(shù)。如果你的大腦保持著Excel處理數(shù)據(jù)的思維慣性燕酷,在切換到pandas解決類似問題時就會遇到困難[1]籍凝。transform就是這樣一個函數(shù)。我已經(jīng)使用pandas有一段時間了苗缩,但是還沒有機會使用它饵蒂,所我最近花了點時間去了解下他的用法,以及他能干些什么酱讶。這篇文章通過一個例子來演示transform如何在匯總數(shù)據(jù)時提示效率的退盯。

什么是transform?

對于transform介紹的最好的是jake VanderPlas的書Python Data Science Handbook,就像書中提到的,transform函數(shù)是用來配合groupby操作的渊迁。這里假定大多數(shù)讀者都可能都經(jīng)常使用groupby中的aggregate,filter或者apply來匯總數(shù)據(jù)慰照。但是transform跟這些相比理解起來有點小小困難,特別是對那些Excel用戶來說琉朽。這里并不是說transform概念復雜毒租,而是需要一個思路上的轉換。jake將他的書已jupyter notebook形式發(fā)布,通過閱讀可以了解下為什么transform'非常特別箱叁。

aggregation操作返回壓縮版本的數(shù)據(jù)墅垮,transformation可以返回經(jīng)過完整數(shù)據(jù)經(jīng)過轉換的版本。經(jīng)過轉換耕漱,輸出的數(shù)據(jù)和輸入的數(shù)據(jù)結構相同

With that basic definition, I will go through another example that can explain how this is useful in other instances outside of centering data.

problem set

在這個例子中噩斟,我們將會虛構一個銷售數(shù)據(jù):點我下載,為了節(jié)約篇幅,這里只保留12行孤个。

account name order sku quantity unit price ext price
0 383080 Will LLC 10001 B1-20000 7 33.69 235.83
1 383080 Will LLC 10001 S1-27722 11 21.12 232.32
2 383080 Will LLC 10001 B1-86481 3 35.99 107.97
3 412290 Jerde-Hilpert 10005 S1-06532 48 55.82 2679.36
4 412290 Jerde-Hilpert 10005 S1-82801 21 13.62 286.02
5 412290 Jerde-Hilpert 10005 S1-06532 9 92.55 832.95
6 412290 Jerde-Hilpert 10005 S1-47412 44 78.91 3472.04
7 412290 Jerde-Hilpert 10005 S1-27722 36 25.42 915.12
8 218895 Kulas Inc 10006 S1-27722 32 95.66 3061.12
9 218895 Kulas Inc 10006 B1-33087 23 22.55 518.65
10 218895 Kulas Inc 10006 B1-33364 3 72.30 216.90
11 218895 Kulas Inc 10006 B1-20000 -1 72.18 -72.18

如果所見剃允,表中有三個訂單(10001, 10005 and 10006) ,每個訂單包含多個產(chǎn)品齐鲤。

現(xiàn)在我們想通過以上數(shù)據(jù)知道:每個產(chǎn)品占總訂單百分比
例如斥废,加入我們知道訂單10001總計金額是576.12,那么這個訂單下面每個產(chǎn)品的價值比例依次是。

  • B1-20000 = $235.83 or 40.9%
  • S1-27722 = $232.32 or 40.3%
  • B1-86481 = $107.97 or 18.7%
    通常要計算這些信息给郊,并且添加到原表中應該如何實現(xiàn)呢牡肉?先計算每個訂單的總價,然后將這些數(shù)據(jù)置回明細表淆九,得到百分比统锤。在Excel中,你可以通過分類匯總計算值炭庙。

第一種方法-合并

如果你非常熟悉pandas,你可能會先進行分組饲窿,得到一個新的DataFrame,然后進行合并焕蹄,經(jīng)過系列步驟得到最終結果逾雄,你可能通常是這樣擦做的
導入模塊,讀取數(shù)據(jù)

import pandas as pd
df = pd.read_excel("sales_transactions.xlsx")

然后腻脏,你會通過groupby根據(jù)訂單號進行分組鸦泳,然后使用sum函數(shù)對價格進行匯總。

df.groupby('order')["ext price"].sum()
order
10001     576.12
10005    8185.49
10006    3724.49
Name: ext price, dtype: float64

下面這張圖演示了進行groupby操作時發(fā)生了什么永品。

groupby:split做鹰、apply、combine

最關鍵的部分是鼎姐,如何將分組后的計算結果拼接到原始數(shù)據(jù)中钾麸,本能的想法是利用聚合數(shù)據(jù)創(chuàng)建一個新的dataframe掉弛,然后通過merge執(zhí)行右連接拼接到原始數(shù)據(jù)。

order_total = df.groupby('order')["extprice"].sum().rename("Order_Total").reset_index()
df_1 = df.merge(order_total)
#merge的時候省略了一些細節(jié)喂走,因為有共同字段Order,所以自動對齊谋作,實際上相當于df.merge(order_total,on ='order',how = left)
df_1["Percent_of_Order"] = df_1["ext price"] / df_1["Order_Total"]
account name order sku quantity unit price ext price order total Order_Total Percent_of_Order
0 383080 Will LLC 10001 B1-20000 7 33.69 235.83 576.12 576.12 0.409342
1 383080 Will LLC 10001 S1-27722 11 21.12 232.32 576.12 576.12 0.403249
2 383080 Will LLC 10001 B1-86481 3 35.99 107.97 576.12 576.12 0.187409
3 412290 Jerde-Hilpert 10005 S1-06532 48 55.82 2679.36 8185.49 8185.49 0.327330
4 412290 Jerde-Hilpert 10005 S1-82801 21 13.62 286.02 8185.49 8185.49 0.034942
5 412290 Jerde-Hilpert 10005 S1-06532 9 92.55 832.95 8185.49 8185.49 0.101759
6 412290 Jerde-Hilpert 10005 S1-47412 44 78.91 3472.04 8185.49 8185.49 0.424170
7 412290 Jerde-Hilpert 10005 S1-27722 36 25.42 915.12 8185.49 8185.49 0.111798
8 218895 Kulas Inc 10006 S1-27722 32 95.66 3061.12 3724.49 3724.49 0.821890
9 218895 Kulas Inc 10006 B1-33087 23 22.55 518.65 3724.49 3724.49 0.139254
10 218895 Kulas Inc 10006 B1-33364 3 72.30 216.90 3724.49 3724.49 0.058236
11 218895 Kulas Inc 10006 B1-20000 -1 72.18 -72.18 3724.49 3724.49 -0.019380

這樣當然沒問題芋肠,但是要經(jīng)過很多中介步驟。

第二種方法:使用Transform

使用之前的數(shù)據(jù)遵蚜,我們看看transformgroupby能得到什么

df.groupby('order')["ext price"].transform('sum')
0      576.12
1      576.12
2      576.12
3     8185.49
4     8185.49
5     8185.49
6     8185.49
7     8185.49
8     3724.49
9     3724.49
10    3724.49
11    3724.49
dtype: float64

你可以看到帖池,單純的groupby進行sum聚合得到的數(shù)據(jù)尺寸和transform不同。普通聚合函數(shù)返回聚合以后的結果吭净,而transform返回的計算結果保留的原始數(shù)據(jù)的索引睡汹,這就是transform的獨特性。
借此寂殉,我們可以不用費什么腦子囚巴,兩部結算處結果

df["Order_Total"] = df.groupby('order')["ext price"].transform('sum')
df["Percent_of_Order"] = df["ext price"] / df["Order_Total"]
account name order sku quantity unit price ext price order total Order_Total Percent_of_Order
0 383080 Will LLC 10001 B1-20000 7 33.69 235.83 576.12 576.12 0.409342
1 383080 Will LLC 10001 S1-27722 11 21.12 232.32 576.12 576.12 0.403249
2 383080 Will LLC 10001 B1-86481 3 35.99 107.97 576.12 576.12 0.187409
3 412290 Jerde-Hilpert 10005 S1-06532 48 55.82 2679.36 8185.49 8185.49 0.327330
4 412290 Jerde-Hilpert 10005 S1-82801 21 13.62 286.02 8185.49 8185.49 0.034942
5 412290 Jerde-Hilpert 10005 S1-06532 9 92.55 832.95 8185.49 8185.49 0.101759
6 412290 Jerde-Hilpert 10005 S1-47412 44 78.91 3472.04 8185.49 8185.49 0.424170
7 412290 Jerde-Hilpert 10005 S1-27722 36 25.42 915.12 8185.49 8185.49 0.111798
8 218895 Kulas Inc 10006 S1-27722 32 95.66 3061.12 3724.49 3724.49 0.821890
9 218895 Kulas Inc 10006 B1-33087 23 22.55 518.65 3724.49 3724.49 0.139254
10 218895 Kulas Inc 10006 B1-33364 3 72.30 216.90 3724.49 3724.49 0.058236
11 218895 Kulas Inc 10006 B1-20000 -1 72.18 -72.18 3724.49 3724.49 -0.019380

如果你不需要中間字段(匯總字段),可以一步得出百分比

df["Percent_of_Order"] = df["ext price"] / df.groupby('order')["ext price"].transform('sum')

下圖演示了transform的工作邏輯,可以對照下之前groupby

transform-example.png

通過上面的例子友扰,我相信你也認為transform功能非常強大彤叉。

譯者討論

以前我解決這類問題的思路是先groupby,然后通過自己寫的lambda函數(shù)查找到結果在apply到新列中,通過第一個例子村怪,才知道m(xù)erge原來是這樣用的秽浇,缺少sql的思維真是害死人。


  1. 這段翻譯可能謬誤比較大 ?

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末甚负,一起剝皮案震驚了整個濱河市柬焕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梭域,老刑警劉巖斑举,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異病涨,居然都是意外死亡懂昂,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門没宾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凌彬,“玉大人,你說我怎么就攤上這事循衰〔玻” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵会钝,是天一觀的道長伐蒋。 經(jīng)常有香客問我工三,道長,這世上最難降的妖魔是什么先鱼? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任俭正,我火速辦了婚禮,結果婚禮上焙畔,老公的妹妹穿的比我還像新娘掸读。我一直安慰自己,他們只是感情好宏多,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布儿惫。 她就那樣靜靜地躺著,像睡著了一般伸但。 火紅的嫁衣襯著肌膚如雪肾请。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天更胖,我揣著相機與錄音铛铁,去河邊找鬼。 笑死却妨,一個胖子當著我的面吹牛避归,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播管呵,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼梳毙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捐下?” 一聲冷哼從身側響起账锹,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坷襟,沒想到半個月后奸柬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡婴程,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年廓奕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片档叔。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡桌粉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衙四,到底是詐尸還是另有隱情铃肯,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布传蹈,位于F島的核電站押逼,受9級特大地震影響步藕,放射性物質發(fā)生泄漏。R本人自食惡果不足惜挑格,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一咙冗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漂彤,春花似錦雾消、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽确镊。三九已至士骤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蕾域,已是汗流浹背拷肌。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留旨巷,地道東北人巨缘。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像采呐,于是被迫代替她去往敵國和親若锁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容