原文地址: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#上去了。

用例: 使用同一数据的多个视图

对于运行时性能,尤其是对于大规模的数据集而言,能够在不进行复制的情况下仅对函数传入和传出原始数据的本地部分(例如:一张大图片中的一部分)是至关重要的。切片使用局部坐标进行索引的,因此您的算法无需了解数据的全局结构,这样就有效地简化了您的工作,并确保尽可能高的性能,因为避免了不必要的复制。

用例:稀疏视图和递归切片

除了对切片的范围指定start和end之外,再通过指定它的步长,就可以创建数组的稀疏视图了。这是一个连C# 8.0新的数组切片语法都没有的功能(据我所知)。在使用交错数据时,此功能变得非常重要。您可以通过设计算法来让它们处理连的续数据并为它们提供模拟连续数据源的稀疏切片,从而尽可能降低算法的复杂性。

切片可以进一步切片,如果您使用高维数据的话,这也将是一个非常重要的功能。同时这也有助于减少算法的复杂性,因为通过递归切片减少了数据的维数。

用例:高效地处理高维数据

如果您需要将数据数组视为一个卷,并在不需要进行令人烦躁的坐标转换计算的情况下使用其中的某些部分,那么.reshape()方法就是您的朋友。

所有由.reshape()或切片操作创建的数组都只是原始数据的视图。当您对视图的元素进行迭代、读取或写入时,其实您访问的是原始的数据数组。很显然,NumSharp为您做了相应的索引变换,所以您可以使用相对的坐标对切片进行索引。

用例:在无任何额外成本的情况下颠倒元素的顺序

使用值为负数的步长可以高效的反转切片的顺序。它的优点是不需要复制或列举数据就可以完成此操作,就像IEnumerable.Reverse() 一样。区别在于,视图(就是指a["::-1"]的操作结果)以相反的顺序显示数据,此外您无需对其进行列举就可以索引到该反转序列。

用例:通过减少维度来降低复杂性

当处理高维数据时,该数据的算法也会变得非常复杂。在处理NumSharp的NDArray的.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最近的这次改进就是实现这一目标的重要基石。

[翻译] NumSharp的数组切片功能 [:]的更多相关文章

  1. NumSharp的数组切片功能

    NumSharp的数组切片功能 原文地址:https://medium.com/scisharp/slicing-in-numsharp-e56c46826630 翻译初稿(英文水平有限,请多包涵): ...

  2. 窥探Swift之数组安全索引与数组切片

    今天是元宵节,祝大家元宵节快乐!在Swift中的数组和字典中下标是非常常见的,数组可以通过索引下标进行元素的查询,字典可以通过键下标来获取相应的值.在使用数组时,一个常见的致命错误就是数组越界.如果在 ...

  3. GO中的数组切片

    GO中的数组切片可以看做是功能更强大的数组,在append数据时,可以自动调整内存大小以适应数据实际大小,有些类似于C#中的List<T>. GO 中数组切片的“容量”与实际储存的大小可以 ...

  4. Python进阶:自定义对象实现切片功能

    2018-12-31 更新声明:切片系列文章本是分三篇写成,现已合并成一篇.合并后,修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章节衔接做了大量改动.原系列的单篇就不删除了,毕竟也是 ...

  5. Go语言中的数组与数组切片

    Go中的数组与C的数组一样,只是定义方法不同 c: int a[10][10] Go [10][10]int 定义并初始化 array1 := [5]int{1,2,3,4,5} 变量名 := [in ...

  6. Numpy数组基本操作(数组索引,数组切片以及数组的形状,数组的拼接与分裂)

    一:数组的属性 每个数组都有它的属性,可分为:ndim(数组的维度),shape(数组每个维度的大小),size(数组的总大小),dtype(数组数据的类型) 二:数组索引 和python列表一样,N ...

  7. golang中不定参数与数组切片的区别

    package main import "fmt" func main() { myfunc1(, , , ) //传递不定数量的参数 myfunc2([], , , }) //传 ...

  8. go语言 类型:数组切片

    初看起来,数组切片就像一个指向数组的指针,实际上它拥有自己的数据结构,而不仅仅是个指针.数组切片的数据结构可以抽象为以下3个变量: 1.一个指向原生数组的指针: 2.数组切片中的元素个数: 3.数组切 ...

  9. C#二进制字节数组操作功能 拦截字节数组SubByte

    C#二进制字节数组操作功能 拦截字节数组SubByte /// <summary> /// 截取字节数组 /// </summary> /// <param name=& ...

随机推荐

  1. Ajax原生代码

    Ajax传数据有两种方式:get/post.下面是前台的get/post方式的代码. //------------原生--------- function AjaxGET(){ //第一步 调用Aja ...

  2. Applied Nonparametric Statistics-lec8

    Ref:https://onlinecourses.science.psu.edu/stat464/print/book/export/html/11 additive model value = t ...

  3. Linux异常处理体系结构

    arm11处理器裸机的异常与中断处理参考: [OK6410裸机程序]异常处理 [OK6410裸机程序]按键中断 另外参考一篇:Linux中断体系结构 在ARM V4及V4T以后的大部分处理器中,中断向 ...

  4. AreYouBusy HDU - 3535 (dp)

    AreYouBusy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. UVA - 11134 Fabled Rooks问题分解,贪心

    题目:点击打开题目链接 思路:为了满足所有的车不能相互攻击,就要保证所有的车不同行不同列,于是可以发现,行与列是无关的,因此题目可以拆解为两个一维问题,即在区间[1-n]之间选择n个不同的整数,使得第 ...

  6. 稀疏表(ST / Sparse Table)

    RMQ问题: 给定一个序列,每次询问一个区间最小值 / 最大值. 没有修改. //拿区间最大值来举例. memset(ans, -INF, sizeof(ans)); for (int i = 1; ...

  7. 记一次虚拟机无法挂载volume的怪异问题排查

    故障现象 使用nova volume-attach <server> <volume>命令挂载卷,命令没有返回错误,但是查看虚拟机状态,卷并没有挂载上. 故障原因 疑似虚拟机长 ...

  8. bash函数定义/使用/传参…

    函数:function, 功能     过程式编程,代码重用         模块化编程         简洁             语法:         function f_name {    ...

  9. BZOJ 3326: [Scoi2013]数数

    数位DP,然而式子真的复杂 #include<cstdio> #include<algorithm> #include<cstring> using namespa ...

  10. 1章 perl入门

    1.标量数据    单变量    数字和字符串两种情况 2.所有数字的内部格式都相同.浮点型   perl中没有应对整数值得运算   . 3.浮点数直接量 数字e表示10的次方标示符 例子:-6.5e ...