標籤:

Pandas中的鏈式方法

鏈式方法是當前比較流行的一種語法規則。 在過去的幾個版本中,我們已經提到了幾個支持鏈式方法的函數:

  • assign (0.16.0): 用於往 DataFrame 中增加新變數(類似於 dplyr 中的 mutate 函數)
  • pipe (0.16.2): 用於包含用戶自定義的鏈式方法
  • rename (0.18.0): 用於改變軸名稱
  • Window methods (0.18): 利用類似於 groupby 的 API 介面調用 pd.rolling* 和 pd.expanding* 頂層函數的 NDFrame 方法。

本文將從一個簡單的例子說起:

我覺得鏈式方法的代碼非常易讀,但是有些人卻並了解它。它並不像重嵌套函數那樣循環調用參數,它的所有代碼和流程都是自上而下運行的,這大大增強了代碼的可讀性。

我最喜歡的示例來自 Jeff Allen,比較以下這兩段功能相同但風格迥異的代碼:

對比上述兩種風格的代碼,你會發現即使你不知道 R 語言中管道符號 %>% 的功能,你也能很輕易地看懂第二段代碼。而對於第一段代碼而言,你需要弄清楚代碼的執行順序以及如何處理相應的函數參數。

作為讀者,你可能會說你不會寫出類似於重嵌套風格的代碼,但是大多數情況下你的代碼應該是如下所示:

我非常不喜歡這個風格的代碼,因為我需要花費很多時間來思考如何對變數進行命名。這是非常令人困擾的事情,因為我們根本不關心 on_hill 這些中間變數。

上述代碼的第四種實現方法是可行的,假設你擁有一個 JackAndJill 對象並且你可以自定義一些方法。那麼你可以實現類似於 R 語言中的管道功能:

但是這種方法的問題在於如果的數據不是 ndarray 或者 DataFrame 或者 DataArray,那麼上述的方法就不存在了。而且我們很難對 DataFrame 的子類進行拓展從而來適應自定義的方法。同時,你所創建的從 DataFrame 中繼承的子類可能僅適用於你自己的代碼,無法和其他方法進行交互操作,因此你的代碼將會非常零散。

或者你可以往 pandas 的項目中提交新的 pull request,從而實現自己的方法。但是你需要說服該項目的維護者,你的新方法值得加入到該項目中並維護之。而且 DataFrame 目前已經擁有超過 250 種的方法,因此我們不願意增加更多的方法。

DataFrame.pipe 的第一個參數是 DataFrame,我們只需要指明後續的參數即可。

成本

過長的鏈式代碼的缺點是調試比較麻煩。由於沒有生成中間變數值,所以如果代碼出問題了,我們無法直接定位出問題在哪。Python 中的生成器也有類似的問題,藉助生成器機制我們可以降低計算機內存消耗,但是此時我們比較難調試程序。

就我常用的探索分析過程而言,這並不是一個大問題。我平常處理的都是不會再更新的數據集,而且對原始數據集進行加工的步驟也不多。

對於規模較大的工作流程,你可能需要藉助 pandas 的其他功能,比如 Airflow 或者 Luigi。 對於需要重複運行的中等規模 ETL 工作流程,我將藉助裝飾器來審查 DataFrame 每個工作步驟所產生的屬性日誌。

藉助我之前製作的一個用於驗證管道中數據集有效性的軟體庫 engarde,我們可以很好地完成工作。

Inplace?

大多數 pandas 的方法都有一個默認值為 False 的關鍵詞 inplace。通常來說,你不應該做 inplace 運算。

首先,如果你喜歡用鏈式規則來寫代碼的話,你肯定不會用 inplace 運算,因為這會導致最終返回的結果是 None,並中斷相應的管道鏈。

其次,我懷疑存在一個適合 inplace 運算的構思模型。也就是說,最終結果並不會被分配到額外的存儲器中。但實際上這可能是不真實的,pandas 中還存在許多下述用法:

最後,類似於 ibis 或者 dask 這種類型的項目 inplace 運算並沒有任何意義,因為此時你需要處理表達式或者建立可執行的 DAG 任務,而不僅僅是處理數據而已。

我覺得到此為止我並沒有怎麼寫代碼,更多的是在介紹一些額外的東西,我對此感到非常抱歉。接下來,讓我們做一些探索性分析吧。

一架一天執行多趟航班執飛任務的飛機「堵機」了,會導致靠後的航班延誤更長時間嗎?

一天中較晚起飛的航班會延誤更長時間嗎?

我們將延誤超過十小時的數據視為異常值並將其剔除掉。

接下來,我們僅考慮確實發生延誤的航班數據。

哪個航班的延誤情況最嚴重呢?

哪個航空公司的延誤情況最嚴重呢?

B6 是美國捷藍航空公司。

I wanted to try out scikit-learns new Gaussian Process module so heres a pretty picture.

謝謝閱讀本文!由於我們更多地討論了關於代碼風格的問題而不是介紹實際案例操作,所以本文所介紹的內容比較抽象。謝謝你們的包容,下次我將介紹一個偏實務的話題!

weixin.qq.com/r/WkMCGqv (二維碼自動識別)

原文鏈接:DatasFrame

原文作者:Tom Augspurger

譯者:Fibears
推薦閱讀:

TAG:Python |