[翻译] 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最近的此次改进就是实现这一目标的重要基石。

相关文章
相关标签/搜索