解一道反常的Pandas題(附源數(shù)據(jù)和代碼)
大家好,我是寶器
潘大師(Pandas)基礎教程和實戰(zhàn)案例我寫了不少,增、刪、改、查這樣的常規(guī)操作,感興趣的同學多看、多練基本上都能掌握的差不多。
但是,實際業(yè)務場景,由于各種原因,總會有一些反常的需求。今天這個反常又有代表性的需求,來源于粉絲的提問,相關數(shù)據(jù)已經做了完全脫敏處理,供大家實戰(zhàn)練手。
需求背景
有兩張表,A表記錄了很多款產品的三個基礎字段,分別是產品ID,地區(qū)代碼和重量:

B表是運費明細表,這個表結構很“業(yè)務”。每行對應著單個地區(qū),不同檔位重量,所對應的運費:

比如121地區(qū),0-0.5kg的產品,運費是5.38元;2.01(實際應該是大于1)-3kg,運費則是5.44元。
現(xiàn)在,我們想要結合A表和B表,統(tǒng)計出A表每個產品付多少運費,應該怎么實現(xiàn)?
可以先自己思考一分鐘
解題思路
人海戰(zhàn)術
任何數(shù)據(jù)需求,在人海戰(zhàn)術面前都是弟弟。
A表一共215行,我們只需要找215個人,每個人只需要記好自己要統(tǒng)計那款產品的地區(qū)代碼和重量字段,然后在B表中根據(jù)地區(qū)代碼,找到所在地區(qū)運費標準,然后一眼掃過去,就能得到最終運費了。
兩個“只需要”,問題就這樣easy的解決了。
問題變成了,我還差214個人。
解構戰(zhàn)術
通過人海戰(zhàn)術,我們其實已經明確了解題的樸素思路:根據(jù)地區(qū)代碼和重量,和B表匹配,返回運費結果。
難點在于,B表是偏透視表結構的,運費是橫向分布,用Pandas就算用地區(qū)代碼匹配,還是不能找到合適的運費區(qū)間。
怎么辦呢?
如果我們把B表解構,變成“源數(shù)據(jù)”格式,問題就全部解決了:

轉換完成后,和A表根據(jù)地區(qū)代碼做一個匹配篩選,答案就自己跑出來了。
下面是動手時刻。
具體實現(xiàn)
先導入數(shù)據(jù),A表(product):

B表(cost):

要想把B表變成“源數(shù)據(jù)”的格式,關鍵在于理解stack()堆疊操作,結合示例圖比較容易搞懂:

通過stack操作,把多列變?yōu)閱瘟卸嘈?,原本?列數(shù)據(jù)堆成了1列,從而方便了一些場景下的匹配。要變回來也很簡單,unstack即可:

在我們的具體場景中,先指定好不變的索引列,然后直接上stack:

這樣,就得到了我們目標的源數(shù)據(jù)。接著,A表和B表做匹配:

值得注意的是,因為我們根據(jù)每個地方的重量區(qū)間做了堆疊,這里的匹配結果,每個產品保留了對應地區(qū),所有重量區(qū)間的價格,離最終結果還有一步之遙。
需要把重量區(qū)間做拆分,從而和產品重量對比,找到對應的重量區(qū)間:

接著,根據(jù)重量的最低、最高區(qū)間,判斷每一行的重量是否符合區(qū)間:

最后,篩選出符合區(qū)間的產品,及對應的價格等字段:

大功告成~

推薦閱讀
歡迎長按掃碼關注「數(shù)據(jù)管道」
