天天看點

牛!NumPy團隊發了篇Nature

牛!NumPy團隊發了篇Nature

0 首先要知道Numpy是啥文獻摘要

  • 數組程式設計為通路和操作矢量、矩陣和高維數組中的資料提供了強大的文法。
  • NumPy是Python語言的主要數組程式設計庫。它在實體、化學、天文學、地學、生物學、心理學、材料科學、工程、金融和經濟等不同領域的研究分析中發揮着至關重要的作用。
  • NumPy是建構科學Python生态系統的基礎。

在這裡,我們回顧幾個基本的數組概念,展示一個簡單而強大的用于分析科學資料的程式設計範例。

牛!NumPy團隊發了篇Nature

2 Numpy數組

2.1資料結構

牛!NumPy團隊發了篇Nature

NumPy數組是有效存儲和通路多元數組(張量)的資料結構,并且能夠進行各種科學計算。它包括一個指向記憶體的指針,以及用于解釋存儲在那裡的資料的中繼資料,特别是“data type”、“shape”和“strides”。

data type描述數組中存儲的元素的性質。數組隻有一種資料類型,并且數組的每個元素在記憶體中占用相同數量的位元組。資料類型的示例包括real and complex numbers, strings, timestamps and pointers to Python objects.

shape決定了沿每個軸的元素數量,軸的數量就是數組的次元。例如,數字矢量可以存儲為形狀為N的一維數組,而彩色視訊則是形狀為(T,M,N,3)的四維數組。

Strides是将線性存儲元素的計算機記憶體解釋為多元數組所必需的,描述了在記憶體中向前移動的位元組數,以便從行跳到行,從列跳到列等等。例如,考慮一個形狀為(4,3)的二維浮點數組,其中每個元素在記憶體中占據8個位元組。要在連續的列之間移動,我們需要在記憶體中向前跳轉8個位元組,要通路下一行,需要3×8=24個位元組。是以該數組的步長為(24,8)。NumPy可以按C或Fortran記憶體順序存儲數組,先疊代行或列。這使得用這些語言編寫的外部庫可以直接通路記憶體中的NumPy數組資料。

2.2索引

使用者使用“索引”(通路子數組或單個元素)、“運算符”以及“array-aware 函數”與NumPy數組互動;這些共同為數組程式設計提供了一個易于閱讀、可表達的進階API,而NumPy則處理快速操作的底層機制。

牛!NumPy團隊發了篇Nature

索引數組将傳回滿足特定條件的單個元素、子數組或元素(b)。

數組甚至可以使用其他數組進行索引(c)。隻要有可能,檢索子數組的索引就會傳回原始數組的“視圖”,以便在兩個數組之間共享資料。這提供了一種在限制記憶體使用的同時對陣列資料子集進行操作的強大方式。

牛!NumPy團隊發了篇Nature

2.3矢量化

牛!NumPy團隊發了篇Nature

為了補充數組文法,NumPy包括對數組執行矢量化計算的函數(代數、統計和三角函數)(d)。矢量化-對整個數組而不是對其單個元素進行操作-對于數組程式設計至關重要。這意味着在C等語言中需要數十行代碼才能表達的操作通常可以實作為一個清晰的Python表達式。這會産生簡潔的代碼,使使用者能夠專注于分析的細節,而NumPy則以近乎最佳的方式處理數組元素的循環-例如,考慮跨度以最大限度地利用計算機的高速緩存記憶體。

2.4廣播

牛!NumPy團隊發了篇Nature

在對兩個形狀相同的數組執行向量化操作(如加法)時,應該發生什麼是很清楚的。通過“廣播”,NumPy允許次元不同,并産生很直覺的結果。一個例子是向數組添加标量值,但是廣播也可以推廣到更複雜的例子,比如縮放數組的每一列或生成坐标網格。在廣播中,一個或兩個數組被虛拟複制(即不複制存儲器中的任何資料),使得操作數的形狀比對(d)。當使用索引數組對數組進行索引時,也可以應用廣播(c)。

2.5縮減

牛!NumPy團隊發了篇Nature

其他函數,如sum、mean和maximum,執行逐個元素的“縮減”,跨單個數組的一個、多個或所有軸聚合結果。例如,對d個軸上的n維數組求和得到維數為n-d的數組(f)。

NumPy還包括array-aware函數,用于建立、重構、連接配接和填補數組;搜尋、排序和計數;以及讀取和寫入檔案。它為生成僞随機數提供廣泛支援,包括各種機率分布。總之,簡單的數組表示、類似數學的文法和各種實用函數使之成為一種高效且強大的數組程式設計語言。

3 Scientific Python ecosystem

牛!NumPy團隊發了篇Nature

Python是一種開源的通用解釋型程式設計語言,非常适合标準程式設計任務,如清理資料、Web互動和解析文本。添加快速數組運算和線性代數使科學家能夠在一種程式設計語言中完成所有工作-這種程式設計語言的優勢是非常容易學習和教授,許多大學采用這種程式設計語言作為主要學習語言就證明了這一點。

SciPy, Matplotlib和NumPy在曆史、發展和使用上是緊密耦合的。SciPy為科學計算提供基本算法,包括數學、科學和工程慣例。Matplotlib生成可供釋出的圖形和可視化效果。NumPy、SciPy和Matplotlib的組合,再加上IPython或Jupyter等進階互動環境,為Python中的數組程式設計提供了堅實的基礎。科學Python生态系統(圖2)在此基礎上建構以提供幾個廣泛使用的特定于技術的庫,這些庫又構成許多特定于領域的項目的基礎。NumPy是生态系統的基礎,它設定了文檔标準,提供了數組測試基礎設施,并增加了對Fortran和其它編譯器的建構支援。

許多研究小組設計了大型、複雜的科學庫,為生态系統添加了特定于應用程式的功能。例如,由Event Horizon Telescope Collaboration開發的用于無線電幹涉成像、分析和模拟的eht-imaging庫依賴于Python科學生态系統的許多較低級别的元件。特别值得一提的是,EHT合作小組利用這個庫首次對黑洞進行成像。在eht-imaging中,NumPy陣列用于存儲和操作處理鍊中的每一步的數字資料:從原始資料到校準和圖像重建。SciPy提供了用于一般圖像處理任務(如過濾和圖像對齊)的工具,而SCRICIT-IMAGE(擴充了SciPy的圖像處理庫)提供了更進階别的功能,如邊緣過濾器和霍夫變換。“scipy.Optimize”子產品執行數學優化。用于複雜網絡分析的軟體包NetworkX用于驗證圖像比較一緻性。Astropy處理标準天文檔案格式并計算時間坐标轉換。Matplotlib用于可視化資料并生成黑洞的最終圖像。

由程式設計基礎陣列和周圍的工具生态系統建立的互動環境-在IPython或Jupyter内部-非常适合探索性資料分析。使用者可以流暢地檢查、操作和可視化他們的資料,并快速疊代以改程序式設計語句。然後将這些語句縫合成指令式或函數式程式,或者包含計算和叙述的筆記本。除了探索性工作之外,科學計算通常是在文本編輯器或內建開發環境(IDE)(如Spyder)中完成的。這種豐富而富有成效的環境讓Python在科學研究中大行其道。

最近資料科學、機器學習和人工智能的快速增長進一步戲劇性地推動了Python的科學使用。其重要應用的例子,例如eht-imaging庫,現在幾乎存在于自然科學和社會科學的每一門學科中。這些工具已經成為許多領域的主要軟體環境。NumPy及其生态系統通常在大學課程、訓練營和暑期學校授課,是世界各地社群會議和研讨會的焦點。NumPy及其API已經變得無處不在。

牛!NumPy團隊發了篇Nature

第一張黑洞圖像 by EHT in 2017

4 Array proliferation and interoperability

NumPy在CPU上提供記憶體中的多元同構類型(即單指針和跨距)數組。它運作在從嵌入式裝置到超級計算機的各種機器上,性能接近編譯語言。在其存在的大部分時間裡,NumPy解決了絕大多數數組計算案例。

然而,科學資料集現在通常會超過一台機器的記憶體容量,可能會存儲在多台機器上,也可能存儲在雲中。此外,最近加速深度學習和人工智能應用的需要導緻了專用加速器硬體的出現,包括圖形處理單元(GPU)、張量處理單元(TPU)和現場可程式設計門陣列(FPGA)。由于其記憶體資料模型,NumPy目前無法直接利用這種存儲和專用硬體。然而,分布式資料以及GPU、TPU和FPGA的并行執行都很好地映射到陣列程式設計的範例:是以,導緻可用的現代硬體架構與利用其計算能力所需的工具之間存在差距。

社群為填補這一空白所做的努力導緻了新數組實作的激增。例如,每個深度學習架構都建立了自己的數組。PyTorch 、TensorFlow 、Apache MXNet和JAX數組都能夠以分布式方式在CPU和GPU上運作,并使用惰性評估來實作額外的性能優化。SciPy和PyData/Sparse都提供稀疏數組,這些稀疏數組通常包含很少的非零值,并且為了提高效率,隻将這些值存儲在記憶體中。此外,還有一些項目将NumPy數組建構為資料容器,并擴充其功能。分布式數組是通過Dask實作的,并通過xarray标記數組,按名稱而不是按索引引用數組的次元,通過xarray将x[:, 1] 與 x.loc[:, 'time']進行比較。

這類庫通常模仿NumPy API,因為這降低了新手進入的門檻,并為更廣泛的社群提供了穩定的程式設計接口陣列。這反過來又防止了分歧,如numeric和numarray之間的分歧。但是探索使用數組的新方法本質上是實驗性的,事實上,幾個很有前途的庫(如Theano和Caffe)已經停止了開發。每次使用者決定嘗試一項新技術時,他們都必須更改import語句,并確定新的庫實作了他們目前使用的NumPy API的所有部分。

理想情況下,使用NumPy函數或語義對專用數組進行操作會很簡單,這樣使用者隻需編寫一次代碼,然後就可以根據需要在NumPy數組、GPU數組、分布式數組等之間進行切換。為了支援外部數組對象之間的數組操作,NumPy是以增加了使用明确指定的API(圖2)充當中央協調機制的功能。

牛!NumPy團隊發了篇Nature

為了促進這種互操作性,NumPy提供了“協定”,允許将專門的數組傳遞給NumPy函數(圖3)。NumPy則根據需要将操作分派到原始庫。支援400多個最流行的NumPy函數。這些協定由廣泛使用的庫實作,如Dask、CuPy、xarray和PyData/Sparse。例如,多虧了這些發展,使用者現在可以使用Dask将他們的計算從單機擴充到分布式系統。這些協定也很好地組合在一起,允許使用者在分布式的多GPU系統上大規模地重新部署NumPy代碼,例如,通過嵌入到Dask數組中的CuPy數組。使用NumPy的進階API,使用者可以在具有數百萬核的多個系統上利用高度并行的代碼執行,所有這些都隻需最少的代碼更改。

這些陣列協定現在是NumPy的一個關鍵功能,預計其重要性隻會增加。NumPy開發人員-其中許多人是這篇評論的作者-疊代地改進和添加協定設計,以提高實用性和簡化采用。

5 讨論

NumPy将數組程式設計的表現力、C語言的性能以及Python的可讀性、可用性和通用性結合在一個成熟的、經過良好測試的、有良好文檔的、由社群開發的庫中。科學Python生态系統中的庫提供了大多數重要算法的快速實作。在需要極度優化的地方,可以使用編譯語言,如Cython、Numba和Pythran;這些語言擴充了Python并透明地加速了瓶頸。由于NumPy的簡單記憶體模型,很容易編寫低級的、手工優化的代碼,通常用C或Fortran來操作NumPy數組,并将它們傳回Python。此外,使用數組協定,可以在對現有代碼進行最小改動的情況下,利用全方位的專用硬體加速。

NumPy最初是由學生、教師和研究人員開發的,目的是為Python提供一個先進的、開源的數組程式設計庫,它可以免費使用,不受許可證伺服器和軟體保護加密狗的限制。我們有一種共同建設一些有意義的東西以造福于他人的感覺。在一個由志同道合的人組成的友好社群中參與這樣的努力,對許多早期貢獻者具有強大的吸引力。

這些使用者開發者經常不得不從頭開始寫代碼來解決他們自己或同僚的問題--通常是用在 Python 之前的低級語言,如 Fortran 和 C。這個新工具的設計參考了其他強大的科學計算互動式程式設計語言,如Basis,Yorick,R和APL,以及商業語言和環境,如IDL(互動式資料語言)和MATLAB。

起初隻是嘗試在Python中添加一個數組對象,後來成為一個充滿活力的工具生态系統的基礎。現在,大量的科學工作依賴于NumPy的正确、快速和穩定。它不再是一個小型的社群項目,而是核心的科學基礎設施。

開發者文化已經成熟:雖然最初的開發是高度非正式的,但NumPy現在已經有了一個路線圖,以及提出和讨論大型變化的過程。該項目有正式的治理結構,并由NumFOCUS提供财政贊助,NumFOCUS是一個非營利性組織,旨在促進研究、資料和科學計算的開放實踐。在過去的幾年裡,該項目吸引了它的第一個資助開發,由摩爾和斯隆基金會贊助,并作為陳-紮克伯格倡議的開源軟體要點計劃的一部分獲得了一個獎項。在這筆資金的支援下,該項目能夠在多個月的時間裡持續關注,實作實質性的新功能和改進。盡管如此,NumPy的開發仍然在很大程度上依賴于研究所學生和研究人員在業餘時間做出的貢獻。

NumPy不再僅僅是科學Python生态系統的基礎數組庫,它已經成為張量計算的标準API,也是Python中數組類型和技術之間的核心協調機制。我們還在繼續努力擴充和改進這些互操作性功能。

在未來十年,NumPy開發者将面臨幾個挑戰。新的裝置将被開發出來,現有的專用硬體也将不斷發展,以應對摩爾定律的收益遞減。将會有更多、更廣泛的資料科學從業者,其中很大一部分将使用NumPy。随着光片顯微鏡和大型巡天望遠鏡(LSST)等裝置和儀器的采用,科學資料收集的規模将繼續擴大。新一代語言、解釋器和編譯器,如Rust、Julia和LLVM,将創造新的概念和資料結構,并決定其可行性。

通過這篇評論中描述的機制,NumPy已經準備好迎接這樣一個不斷變化的環境,并繼續在互動式科學計算中發揮上司作用,盡管這樣做需要政府、學術界和工業界的持續資助。但重要的是,NumPy要想滿足資料科學下一個十年的需求,還需要新一代的研究所學生和社群貢獻者來推動它的發展。

部分機器翻譯可能有誤,原文請戳閱讀更多 [1]

參考資料

[1]

https://www.nature.com/articles/s41586-020-2649-2

numpy教程

[1] 官網 https://numpy.org/[2] NumPy中文網 https://www.numpy.org.cn/[3] 官方文檔的參考書籍《Guide to Numpy》https://ia803206.us.archive.org/13/items/NumPyBook/NumPyBook.pdf

繼續閱讀