Julia中nx1数组和n元素数组的区别

Mik*_*lla 12 julia

在Julia中,如果我定义一个包含1列和n行的数组,它似乎实例化了一个"n元素数组",我不明白它与nx1数组的区别:

julia> a = [1 2 3]
1x3 Array{Int64,2}:
 1  2  3

julia> b = [1;2;3]
3-element Array{Int64,1}:
 1
 2
 3
Run Code Online (Sandbox Code Playgroud)

令人困惑的是,如果我对n元素数组进行两次转置,则返回结果为nx1数组:

julia> transpose(transpose(b))
3x1 Array{Int64,2}:
 1
 2
 3
Run Code Online (Sandbox Code Playgroud)

这导致一些意想不到的(对我而言)行为,如:

julia> size(b) == size(transpose(transpose(b)))
false
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. nx1数组和n元素数组有什么区别?
  2. 如何在nx1不执行像我给出的双转置示例之类的情况下创建数组.

Mat*_* B. 21

快速回答:

  1. 一个nX1或1x n阵列是2维矩阵(即恰好仅具有一行或一列),而你正元件阵列是一维的列向量.
  2. 我认为创建nx1数组文字的最简单方法是采用行向量的转置:[1 2 3]'.另一方面,您可以使用任何n维数组将其平展为1维向量vec.

但是,考虑一下为什么这很重要,这更有启发性.Julia的类型系统完全基于类型,而不是值.数组的维度包含在其类型信息中,但行数和列数不包括在内.因此,nx1矩阵和n元素向量之间的差异在于它们具有不同的类型......并且类型推断引擎不能看到矩阵仅具有一列.

为了从Julia获得最佳性能,您(尤其是核心语言和库设计者)希望编写类型稳定的函数.也就是说,函数应该能够推断出它们将基于参数的类型纯粹返回的类型.这允许编译器通过函数跟踪变量而不会丢失类型的跟踪...这反过来又允许它为该特定类型生成非常高度优化的代码.

现在,再考虑转座.如果你想要一个类型稳定的转置函数,它必须至少返回一个二维数组.如果其中一个维度为1并仍然保持良好的性能,它就不能做一些棘手的事情.

总而言之,关于邮件列表和GitHub问题中的矢量转置仍然有很多讨论.这是一个开始的好地方:问题#2686 :ones(3) != ones(3)'' . 或者对相关问题进行更深入的讨论:问题#3262:将类似张量的对象嵌入具有尾随单例维度的高维对象.两者最终被取代并进入问题#4774:认真对待矢量转置.


Julia 0.6的更新:Julia现在非常重视矢量转置!向量转置现在返回一个特殊RowVector类型,其行为类似于1行矩阵,但附加知识只有一行.它也是对原始矢量的懒惰"视图".通过问题中的例子,这意味着不仅是size(b) == size(transpose(transpose(b)))真的,而且也是如此b'' === b.

在Julia 0.6中指定改变维度的重塑操作也更容易一些.上面的问题2(创建nx1数组)的一个很好的答案是reshape([1,2,3], :, 1).:计算指定的维度以匹配源数组的长度.