[翻譯] NumSharp的數組切片功能 [:]

原文地址:https://medium.com/scisharp/slicing-in-numsharp-e56c46826630git

 

翻譯初稿(英文水平有限,請多包涵):github

因爲Numsharp新推出了數組切片這個牛逼的功能,因此.NET社區距離擁有強大的開源機器學習平臺又近了一步。  
  
Python之因此是機器學習的首選語言,部分緣由就是由於它擁有一些牛逼的庫,例如NumPyTensorflow與此同時,C#開發人員也迫切須要用於機器學習和數據科學的強大開源庫。而NumSharp這個由 SciSharp STACK這個開源組織全力推進的,要把NumPy移植到C#的這個項目,因爲其最近全面實現了切片技術,從而向該目標邁進了一大步。該技術容許對n維數組隨意的建立子集,並將其做爲對原始數據的高效視圖。由於這些,使得它與TensorFlow.net一塊兒成爲了C#中機器學習的有用工具。  

  

到底有啥大不了的?  

若是你沒用過NumPy,你可能不知道切片技術有多好用, Python數組容許經過對必定範圍對元素進行索引來返回數組的一個切片,其索引操做是這樣的:a[start:end:step]。可是,只有使用NumPy複雜巧妙的數組實現,切片才成爲一種真正強大的數據操做技術,若沒有這種技術,機器學習或數據科學就沒法想象了。  算法

  

對於那些不能或不想由於機器學習就轉換到Python語言的人來講,幸運的事情發生了,我對此也很羨慕, NumSharp將這種能力帶入了.NET世界裏。做爲NumSharp的開發人員之一,我將向您展現幾個重要的切片用例,並附有C#的示例代碼段。首先請注意,因爲語言語法的不一樣,在C#中沒法以與Python相同的方式進行索引。可是,咱們決定保留Python裏切片定義的語法,所以在C#裏,咱們使用字符串來索引切片。   數組

 

 

而使用NumSharp寫出的C#代碼也是差很少同樣的。但請注意,這裏有一個細微的差異是,這裏的切片使用的是字符串做爲索引器的參數進行的索引。 數據結構

  

正如您所看到的,NumSharp團隊花了不少的精力來保證代碼儘量的與Python類似。 這很是重要,由於這樣的話,現有的依賴於NumPy的代碼就能夠很輕鬆的移植到C#上去了。 機器學習

 

用例使用同一數據的多個視圖 

對於運行時性能,尤爲是對於大規模的數據集而言,可以在不進行復制的狀況下僅對函數傳入和傳出原始數據的本地部分(例如:一張大圖片中的一部分)是相當重要的。切片使用局部座標進行索引的,所以您的算法無需瞭解數據的全局結構,這樣就有效地簡化了您的工做,並確保儘量高的性能,由於避免了沒必要要的複製。 函數

 

用例:稀疏視圖和遞歸切片  

除了對切片的範圍指定startend以外,再經過指定它的步長,就能夠建立數組的稀疏視圖了。這是一個連C# 8.0新的數組切片語法都沒有的功能(據我所知)。在使用交錯數據時,此功能變得很是重要。您能夠經過設計算法來讓它們處理連的續數據併爲它們提供模擬連續數據源的稀疏切片,從而儘量下降算法的複雜性。 工具

切片能夠進一步切片,若是您使用高維數據的話,這也將是一個很是重要的功能。同時這也有助於減小算法的複雜性,由於經過遞歸切片減小了數據的維數。 性能

 

用例:高效地處理高維數據 

若是您須要將數據數組視爲一個卷,並在不須要進行使人煩躁的座標轉換計算的狀況下使用其中的某些部分,那麼.reshape()方法就是您的朋友。 學習

全部由.reshape()或切片操做建立的數組都只是原始數據的視圖。當您對視圖的元素進行迭代、讀取或寫入時,其實您訪問的是原始的數據數組。很顯然,NumSharp爲您作了相應的索引變換,因此您可使用相對的座標對切片進行索引。 

 

用例:在無任何額外成本的狀況下顛倒元素的順序 

使用值爲負數的步長能夠高效的反轉切片的順序。它的優勢是不須要複製或列舉數據就能夠完成此操做,就像IEnumerable.Reverse() 同樣。區別在於,視圖(就是指a["::-1"]的操做結果)以相反的順序顯示數據,此外您無需對其進行列舉就能夠索引到該反轉序列。 

 

用例:經過減小維度來下降複雜性 

當處理高維數據時,該數據的算法也會變得很是複雜。在處理NumSharpNDArray.ToString() 方法時(這個方法能夠打印出任意高維卷)我注意到該算法經過系統地和遞歸地將(N-1)D卷切出ND-卷等諸如此類的方式簡單而優雅的取得告終果。 

經過在可返回低維子卷的範圍符號上使用NumSharp的索引符號進行切片,才使這種分而治之的方法變得可行。 

  

範圍符號 vs 索引符號 

範圍符號[「start:stop:step」]容許您訪問具備相同維度給定卷的子範圍。因此即便只劃出二維矩陣的一列,仍然能夠獲得只有一列的二維矩陣。下面這一小段C#代碼就展現了這一點: 

數組字符索引重載能夠實如今一個N維數組裏從特定位置建立視圖。所以,用索引符號從二維矩陣中分割出一個列,能夠獲得一個一維向量: 

若是您一眼也沒有發現差別,那麼下面這兩個切片定義, ange [":,2:3"] vs index [":,2"],它們的結果是大不相同的。NumSharp wiki提供了新切片表示法的完整參考 

 

附註:ArraySlice <T> 

在實現N維視圖的切片時,我得出這樣一個結論,對於.NET中的許多其餘領域來講它可能頗有趣,所以我將它分解出一個本身的獨立庫SliceAndDice它裏面有個東西叫作ArraySlice <T>,它是對全部索引的C#數據結構(如T[]IList<T>)的一個輕量級包裝,此外它還容許您使用相同的塑形,切片和視圖機制,而且無需進行任何其餘的重度數值計算。它只使用了幾百行代碼就漂亮簡潔的完成了切片的壯舉。 

  

綜上

NumSharp最近被賦予了切片和視圖機制,一樣就是這些機制讓NumPy成爲Python機器學習生態最重要的庫之一。SciSharp Stack做爲一個開源組織,目前只有少數技術嫺熟的開發人員,但他們卻很是努力地要爲.NET世界帶來一樣的魔力。NumSharp最近的此次改進就是實現這一目標的重要基石。

相關文章
相關標籤/搜索