解一道反常的 pandas 題

潘大師(Pandas)基礎教程和實戰案例我寫了不少,增、刪、改、查這樣的常規操作,感興趣的同學多看、多練基本上都能掌握的差不多。

但是,實際業務場景,由於各種原因,總會有一些反常的需求。今天這個反常又有代表性的需求,來源於粉絲的提問,相關數據已經做了完全脫敏處理,供大家實戰練手。

需求背景

有兩張表,A 表記錄了很多款產品的三個基礎字段,分別是產品 ID,地區代碼和重量:

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

比如 121 地區,0-0.5kg 的產品,運費是 5.38 元;2.01(實際應該是大於 1)-3kg,運費則是 5.44 元。

現在,我們想要結合 A 表和 B 表,統計出 A 表每個產品付多少運費,應該怎麼實現?

可以先自己思考一分鐘

解題思路

人海戰術

任何數據需求,在人海戰術面前都是弟弟。

A 表一共 215 行,我們只需要找 215 個人,每個人只需要記好自己要統計那款產品的地區代碼和重量字段,然後在 B 表中根據地區代碼,找到所在地區運費標準,然後一眼掃過去,就能得到最終運費了。

兩個 “只需要”,問題就這樣 easy 的解決了。

  解構戰術

通過人海戰術,我們其實已經明確瞭解題的樸素思路:根據地區代碼和重量,和 B 表匹配,返回運費結果。

難點在於,B 表是偏透視表結構的,運費是橫向分佈,用 Pandas 就算用地區代碼匹配,還是不能找到合適的運費區間。

怎麼辦呢?

如果我們把 B 表解構,變成 “源數據” 格式,問題就全部解決了:

轉換完成後,和 A 表根據地區代碼做一個匹配篩選,答案就自己跑出來了。

下面是動手時刻。

具體實現

先導入數據,A 表(product):

B 表(cost):

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

通過 stack 操作,把多列變爲單列多行,原本的 2 列數據堆成了 1 列,從而方便了一些場景下的匹配。要變回來也很簡單,unstack 即可:

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

這樣,就得到了我們目標的源數據。接着,A 表和 B 表做匹配:

值得注意的是,因爲我們根據每個地方的重量區間做了堆疊,這裏的匹配結果,每個產品保留了對應地區,所有重量區間的價格,離最終結果還有一步之遙。

需要把重量區間做拆分,從而和產品重量對比,找到對應的重量區間:

接着,根據重量的最低、最高區間,判斷每一行的重量是否符合區間:

最後,篩選出符合區間的產品,及對應的價格等字段:

大功告成~

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/1opWzdTusw1lZq1goRTzkw