本文示例程式碼已上傳至我的
Github
倉庫https://github.com/CNFeffery/DataScienceStudyNotes
1 簡介
鏈式程式設計是一種非常高效的組織程式碼的方式,典型如pandas
與scikit-learn
中的pipe()
,以及R
中的管道操作符%>%
等,它們都可以幫助我們像連線管道一樣,將計算過程中的不同步驟順滑的連線起來,從而取代繁瑣的函式巢狀以及避免多餘中間變數的建立。
鏈式程式設計與常規寫法的比較如下例:
# 非鏈式寫法
func4(func3(func2(func1(A))))
# 鏈式寫法
A.func1().func2().func3().func4()
哪一種寫法更簡潔明瞭,想必大家一眼就看得出來,而今天的文章就將帶大家認識如何藉助funct
的力量,來改造Python
原生列表,賦予其鏈式計算的能力。
2 利用funct.Array實現鏈式計算
funct
的設計理念就是類似Python列表但更棒,它借鑑了numpy
的很多特點,配合功能豐富的各種鏈式計算方法,使得我們在使用它完成計算任務編寫程式碼如絲般順滑時~
利用pip install funct
完成安裝(本文演示版本為0.9.2)之後,下面我們來認識它的一些優秀特性吧~
2.1 funct.Array的建立
funct
中類比列表和numpy
中的陣列,創造了Array
這種特別的資料結構,常用的有如下幾種建立方式:
- 從其他資料結構建立
最常規的方式是從現有的其他資料結構,轉換到Array
,常見如下面的幾個例子:
- 類似numpy風格的規則建立方法
除了從現成的資料中建立Array
之外,我們還可以類似numpy
中的linspace()
等API那樣,基於規則批量建立資料,常用的有如下兩種方法:
- 建立巢狀Array
既然是建立在列表的基礎上,那麼funct
對巢狀Array
尤其是不規則巢狀Array
的支援也是很到位的:
但在配合多個numpy
陣列構建巢狀Array
時要注意,最後一定要加上toArray()
方法才能徹底完成轉換:
2.2 funct.Array的索引
大致介紹完如何建立funct.Array
之後,很重要的一點就是如何對已有Array
進行索引,在funct
中針對Array
設計瞭如下幾種豐富的索引方式:
- 列表式索引
既然繼承自列表,自然可以使用Python
原生列表的索引與切片方式:
- 陣列式索引
我們都知道Python
原生列表不能傳入一系列標號對應的陣列來一次性索引出多個值,除非轉換為numpy
陣列或pandas
的Series
,但這又會在一些應用場景下丟失靈活性,但在Array
中,它可以!
- Bool值索引
Array
同樣支援傳入Bool
值索引,使得我們可以將某個條件判斷之後的判斷結果作為索引依據傳入:
- 多層索引
既然Array
是支援巢狀結構的,自然可以進行多層索引,但需要注意的是:
2.3 funct.Array的鏈式騷操作
講完了如何建立與索引funct.Array
之後,就來到了本文的重頭戲——Array
的鏈式運算上,在funct.Array
中,幾乎所有常見的數值與邏輯運算都被封裝到方法中,我們來一階一階的來看看不同情況下如何組織程式碼:
- level1:基礎的數值運算
首先我們來看看最基礎的四則運算等操作在Array
中如何鏈式下去:
這樣每一步都很清楚,且每一步都可以獨立新增註釋,保持了程式碼的可讀性,譬如可用於歸一化與標準化的計算上:
- level2:配合map方法推廣元素級別運算
除了使用內建的基礎的運算方法之外,在funct.Array
中還支援配合map()
方法將任意函式應用到每個元素上,從而無限拓寬計算的自由性,譬如我們在前面歸一化的基礎上對資料進行分箱:
- level3:配合zip方法引入其他Array參與運算
當我們想要在鏈式運算中引入其他陣列物件時,就可以用到更高階的zip()
方法,譬如我們想找出多個Array
中相同位置最大值:
- level4:條件分組
在pandas
中我們可以利用groupby()
進行資料分箱並銜接任意形式的運算,在funct.Array
中我們也可以配合groupBy()
方法實現:
而除了本文介紹到的這一點API之外,funct
還提供了上百種實用API,並且還具有並行執行與併發執行等高階特性,感興趣的朋友可以前往官方文件檢視( https://github.com/Lauriat/funct )。
以上就是本文的全部內容,歡迎在評論區與我進行討論~