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


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

 

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

由於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最近的這次改進就是實現這一目標的重要基石。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM