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

Julia中nx1数组与n元素数组的区别,julia,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 julia> transpose(transpose(b)) 3x1 Array{Int64,2}: 1 2 3 令人困惑的是,如果我对一个n元

在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
julia> transpose(transpose(b))
3x1 Array{Int64,2}:
 1
 2
 3
令人困惑的是,如果我对一个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
julia> transpose(transpose(b))
3x1 Array{Int64,2}:
 1
 2
 3
这会导致一些(对我而言)意外的行为,如:

julia> size(b) == size(transpose(transpose(b)))
false
我的问题是:

  • nx1数组和n元素数组之间有什么区别
  • 如何创建
    nx1
    数组而不执行我给出的双转置示例
  • 快速回答:

  • n
    x1或1x
    n
    数组是二维矩阵(恰好只有一行或一列),而n元素数组是一维列向量
  • 我认为创建
    n
    x1数组文本的最简单方法是对行向量进行转置:
    [1 2 3]'
    。另一方面,您可以使用将任何n维数组展平为一维向量

  • 不过,思考一下为什么这一点很重要,会更有启发性。Julia的类型系统完全基于类型,而不是值。数组的维度包含在其类型信息中,但行数和列数不包含在内。因此,nx1矩阵和n元素向量之间的区别在于它们有不同的类型……而类型推理引擎无法看到矩阵只有一列

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

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

    尽管如此,在邮件列表和GitHub问题上,仍然有大量关于向量转置的讨论。这里是一个开始的好地方:。或对相关问题进行更深入的讨论:。两者最终都被取代并合并为一个新的体系


    Julia 0.6的更新:Julia现在非常重视向量转置!向量转置现在返回一个特殊的
    RowVector
    类型,该类型的行为类似于一行矩阵,但还需要知道只有一行。它也是对原始向量的惰性“视图”。对于问题中的示例,这意味着不仅
    size(b)==size(transpose(transpose(b))
    为真,而且
    b'==b

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