在我从事Python开发的这些年里,我总是惊讶地发现,如果你设法重写遍历narray的代码,并使用numpy函数一次处理整个数组,那么事情会变得快得多。最近,我越来越多地转向node,我正在寻找类似的东西。到目前为止,我发现了一些东西,没有一个看起来很有希望:
- scikit-node,用python运行scikit-learn,并与node接口。我还没有试过,但我不指望它能给我我想要的尖端速度。
- 有一些相当老的,和新的,javascript矩阵库(sylvester, gl-matrix,…)。除了不确定它们是否能很好地处理大于4x4的矩阵(这在3D渲染中最有用),它们似乎是原生javascript(和一些,不确定这些,使用webGL加速)。在浏览器上很好,但在节点上不行。
据我所知,npm可以用c++编写,所以我想知道为什么node没有类似numpy的库。社区对node的兴趣还不够吗?是否有希望ES6的特性(列表推导)将允许javascript编译器自动向量化原生JS代码到c++的速度?我还遗漏了什么吗?
编辑,作为对接近投票的回应:注意,我不是在问"做xyz最好的包是什么"。我只是想知道是否有技术原因没有包在节点上做这个,社会原因,或者根本没有原因,只是我错过了一个包。也许是为了避免太多自以为是的批评,我想知道:我有大约10000个矩阵,每个矩阵都是100 x 100。把它们加在一起最好的(*更正,一个合理快速的)方法是什么?
Edit2 经过一番深入调查,我发现我搜索错了。谷歌"node.js科学计算",有一些非常有趣的注释链接:
- https://cs.stackexchange.com/questions/1693/a-faster-leaner-javascript-for-scientific-computing-what-features-should-i-kee
- http://www.quora.com/Can-Node-js-handle-numerical-computation-the-same-way-that-languages-like-R-or-Julia-can
- Javascript和科学处理?
据我所知,到目前为止,基本上没有人打扰。此外,由于js的typedarray中有一些主要的遗漏(例如64位int),因此仅通过使用npm而不破坏引擎本身可能很难添加良好的支持—这将破坏目的。然而,我没有进一步研究最后这句话。
不,没有技术上的原因可以解释为什么Node.js和JavaScript不存在类似numpy的包。
Node.js和JavaScript在数据科学和数字计算社区中获得更多的思想份额有两个主要障碍。
第一个障碍是社区。虽然JavaScript社区规模庞大,但在这个社区中从事数字计算方面有趣工作的人却很少。因此,如果您想在JavaScript和Node.js中进行数值计算,那么寻找帮助您的资源可能会很困难,并且可能感觉像是一种孤独的努力。
其次,缺乏可比较的库(鸡和蛋:需要库来吸引库作者,需要作者来编写好的库)。没有技术上的原因可以解释为什么库不能用JavaScript编写或利用Node.js(例如,通过本地附加组件)。我知道,因为我用JavaScript写过很多数字计算库。因此,虽然在JavaScript中可以实现数字计算,但问题源于无法吸引具有足够专业知识并能够投入时间和精力编写高质量数字计算实现所需的开发人员。
关于OP中提到的具体语言特性:
- ES6/ES2015:最近添加的语言都没有帮助或阻碍JavaScript中数字计算库的开发。像列表解析这样的潜在添加也不会改变游戏规则。对web平台的一个改变是WebAssembly。使用WebAssembly,编译C/c++/Fortran库以在web浏览器中运行将变得更加容易。在回答这个问题的时候,WebAssembly看起来是将SIMD带到web上的一种方法,可能会允许一些加速,尽管重点似乎是短SIMD,而不是长SIMD。但即使有了WebAssembly,将数字计算库移植到网络上也不会像点击编译按钮那么简单。数字计算代码库将需要修改以适应在web上使用,即使这样,也可能需要编写更高级别的api来掩盖一些较低级别的功能,例如手动管理堆。
- 本地附加组件:是的,节点模块可以写成本地附加组件,允许C/c++/Fortran代码在node .js应用程序中使用。个人为此目的编写了库;例如,请参阅stdlib。如果做得好,Node.js可以以与直接使用本机实现相当的速度执行数值计算。
- 类型化数组:正如它们现在的样子,它们适用于数值计算。与C语言类似,您可以创建池缓冲,从而实现高效的内存重用和更好的性能。此外,与R、Python和Julia等语言类似,您可以利用类型化数组来创建ndarray(又名跨行数组)接口。虽然U/Int64整数数组目前还不可用,但(a)它们的缺失并不是一个阻碍,(b)在规范层面上正在推进将U/Int64整数数组添加到JavaScript的建议。对于具有结构化类型的复数也是如此。
我个人认为在JavaScript和Node.js中某种形式的数字计算是不可避免的。数据科学的优势(无处不在,分布,性能)和潜在的应用(边缘计算,集成机器学习,数据可视化)的进化力量太强大,不支持数据科学应用,至少在基本层面上。
disclosure:我和其他人目前正在做一个项目(https://github.com/stdlib-js/stdlib),旨在用JavaScript和Node.js提供数字计算设施。
这是谷歌的TensorFlow.js(以前的https://deeplearnjs.org),它正是这样做的,并且已经内置了使用WebGL在gpu上训练深度神经网络的能力。你也可以将TensorFlow模型移植到它上面。
不要被愚弄,以为这只是深度学习。它是一个完全成熟的数值计算平台,内置GPU加速。它跟随急切的"随你去执行"。模型,如NumPy(和Tensorflow Eager, PyTorch等),而不是"定义然后运行"。像Tensorflow这样的模型。因此,对于以前使用过NumPy的人来说,使用它会感觉很自然。
这里是非常翔实的Github repo:
https://github.com/tensorflow/tfjs我没有尝试过,但是我找到了node-lapack。由于Numpy从使用blas/lapack中获得大部分速度,因此这应该有所帮助。从自述文件来看,它似乎也有一个数组对象,这对于在每次操作中不转换JS和lapack是必不可少的。
这是他们演示的一部分:
var lapack = require('lapack');
var result = lapack.sgeqrf([
[1, 2, 3],
[3, 4, 5],
[5, 6, 7]
]);
console.log(result.R);
console.log(result.tau);
result = sgesvd('A', 'A', [
[1, 2, 3],
[3, 4, 5],
[5, 6, 7]
]);
console.log(result.U);
console.log(result.S);
console.log(result.VT);
result = lapack.sgetrf([
[1, 2, 3],
[3, 4, 5],
[5, 6, 7]
]);
// see the readme for more
它似乎是一个非常直接的接口到lapack使用相同的名称,所以在这方面,它不像Numpy那么方便,但至少它照顾数组的尺寸和东西,应该是一样快(因为大多数工作是由lapack在两种情况下完成的)。
然而,这在浏览器中不起作用,这意味着在任何可以使用它的地方,可能也可以使用Python。就我个人而言,我会坚持使用Python,它在数字方面更占主导地位,除非Python缺少一些特定的Node功能……
numjs是nodejs中一个类似numpy的库。
与@Julius关于deeplearn.js的回答精神相同,tensorflow.js是同一项目的延续。为了在REPL中使用tensorflow模块,我使用以下命令全局安装了它(仅供参考-通常建议不要这样做):
$ npm install --global @tensorflow/tfjs
然后,我运行$ node
来启动节点REPL。
这可能对您有所不同(特别是如果您决定在本地安装tensorflow),但我输入这是为了引用tensorflow模块:
var tf = require('/usr/local/lib/node_modules/@tensorflow/tfjs')
要创建一个1级张量(相当于numpy中的1- d数组),请尝试:
var x = tf.tensor( [-3,4] )
并加上:
x.square().print()
您的输出应该得到[9,16]
。详见https://js.tensorflow.org
我想说tensorflow. JS不仅是numpy的JS替代品,也是sklearn, keras,当然还有tensorflow的替代品。
大多数节点工作似乎都在web"全栈"领域,在快速数字处理具有优势的领域完成的工作要少得多。
在快速数字处理具有优势的领域,Python、R等可能占据主导地位。
结合这两个事实,您最终不会有很多人在节点数字处理库中投入精力。
scijs的narray也不错。https://github.com/scijs/ndarray
var mat = ndarray(new Float64Array([1, 0, 0, 1]), [2,2])
//Now:
//
// mat = 1 0
// 0 1
//
我开始https://www.npmjs.com/package/@nexys/math-ts一个非常简单和轻量级的数字打字库/包
Github: https://github.com/Nexysweb/math-ts