先來看一個實例問題。python
以下銷售數據中展示了三筆訂單,每筆訂單買了多種商品,求每種商品銷售額佔該筆訂單總金額的比例。例如第一條數據的最終結果爲:235.83 / (235.83+232.32+107.97) = 40.93%
。web
後臺回覆「transform」獲取本文所有代碼和pdf版本。api
思路一:
常規的解法是,先用對訂單id分組,求出每筆訂單的總金額,再將源數據和獲得的總金額進行「關聯」。最後把相應的兩列相除便可。相應的代碼以下:微信
1.對訂單id分組,求每筆訂單總額。因爲有三個order
,所以最終會產生三條記錄表示三個總金額。app
2.數據關聯合並ide
爲了使每行都出現相應order的總金額,須要使用「左關聯」。咱們使用源數據在左,聚合後的總金額數據在右(反過來也可)。不指定鏈接key,則會自動查找相應的關聯字段。因爲是多行對一行的關聯,關聯上的就會將總金額重複顯示屢次,恰好符合咱們後面計算的須要。結果如上圖所示。
函數
3.計算佔比學習
有了前面的基礎,就能夠進行最終計算了:直接用商品金額ext_price
除以訂單總額sum_price
。並賦值給新的列pct
便可。url
4.格式調整
爲了美觀,能夠將小數形式轉換爲百分比形式,自定義函數便可實現。
思路二:
對於上面的過程,pandas中的transform
函數提供了更簡潔的實現方式,以下所示:
能夠看到,這種方法把前面的第一步和第二步合成了一步,直接獲得了sum_price
列。這就是transform
的核心:做用於groupby
以後的每一個組的全部數據。能夠參考下面的示意圖幫助理解:
後面的步驟和前面一致。
這種方法在須要對多列分組的時候一樣適用。
多列分組使用transform
爲演示效果,咱們虛構了以下數據,id,name,cls爲維度列。
咱們想求:以(id,name,cls)
爲分組,每組stu的數量佔各組總stu的比例。使用transform
處理以下:
一樣再次計算佔比和格式化,獲得最終結果:
總結transform的用法
transform
函數的官方文檔簽名爲:DataFrame.transform(func,axis=0,*args,**kwargs)
,表示調用func
函數進行轉換,返回轉換後的值,且返回值與原來的數據在相同的軸上具備相同的長度。func
能夠是函數,字符串,列表或字典。具體能夠參考官方文檔:
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.transform.html#pandas.DataFrame.transform。
transform
既能夠和groupby
一塊兒使用,也能夠單獨使用。
1.單獨使用
此時,在某些狀況下能夠實現和apply
函數相似的結果。
2.與groupby一塊兒使用
此時,transform函數返回與原數據同樣數量的行,並將函數的結果分配回原始的dataframe。也就是說返回的shape是(len(df),1)
。本文開頭的例子就是這樣。而apply
函數返回聚合後的行數。例如:
transform
和apply
的另外一個區別是,apply
函數能夠同時做用於多列,而transform
不能夠。下面用例子說明:
上圖中的例子,定義了處理兩列差的函數,在groupby以後分別調用apply
和transform
,transform並不能執行。若是不採用groupby
,直接調用,也會有問題,參見下面的第二種調用方式。
第三種調用調用方式修改了函數,transform
依然不能執行。以上三種調用apply的方式處理兩列的差,換成transform
都會報錯。
利用transform
填充缺失值
transform
另外一個比較突出的做用是用於填充缺失值。舉例以下:
在上面的示例數據中,按照name能夠分爲三組,每組都有缺失值。用平均值填充是一種處理缺失值常見的方式。此處咱們可使用transform對每一組按照組內的平均值填充缺失值。
小結:
transform
函數常常與groupby
一塊兒使用,並將返回的數據從新分配到每一個組去。利用這一點能夠方便求佔比和填充缺失值。但須要注意,相比於apply
,它的侷限在於只能處理單列的數據。
後臺回覆「transform」獲取本文所有代碼和pdf版本。
Reference:
https://www.codenong.com/19966018/
https://www.cnblogs.com/junge-mike/p/12761227.html
https://blog.csdn.net/qq_40587575/article/details/81204514
https://pbpython.com/pandas_transform.html

以清淨心看世界;
用歡喜心過生活。
超哥的雜貨鋪,你值得擁有~
長按二維碼關注咱們
推薦閱讀
本文分享自微信公衆號 - 超哥的雜貨鋪(gh_a624b94bfdab)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。