在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
令人困惑的是,如果我对n元素数组进行两次转置,则返回结果为nx1数组:
julia> transpose(transpose(b))
3x1 Array{Int64,2}:
1
2
3
这导致了一些意想不到的(对我而言)行为,如:
julia> size(b) == size(transpose(transpose(b)))
false
我的问题:
nx1
数组而不执行像我给出的双转置示例。答案 0 :(得分:21)
快速回答:
n
x1或1x n
数组是一个二维矩阵(恰好只有一行或一列),而你的n元素数组是一维列矢量。n
x1数组文字的最简单方法是采用行向量的转置:[1 2 3]'
。另一方面,您可以使用vec
将任何n维数组展平为一维向量。为了从Julia获得最佳性能,您(尤其是核心语言和库设计者)希望编写类型稳定的函数。也就是说,函数应该能够推断出它们将基于参数的类型纯粹返回的类型。这允许编译器通过函数跟踪变量,而不会丢失类型的跟踪...这反过来又允许它为特定类型生成非常高度优化的代码。
现在,再考虑转座。如果你想要一个类型稳定的转置函数,它必须至少返回一个二维数组。如果其中一个维度为1并且仍然保持良好的性能,它就不能做一些棘手的事情。
所有这一切,关于邮件列表和GitHub问题中的矢量转置仍然有很多讨论。这是一个开始的好地方:Issue #2686: ones(3) != ones(3)''
。或者就相关问题进行更深入的讨论:Issue #3262: embed tensor-like objects as higher-dimensional objects with trailing singleton dimensions。两者最终被取代并归入Issue #4774: Taking vector transposes seriously。
Julia 0.6的更新:Julia现在非常重视矢量转置!向量转置现在返回一个特殊的RowVector
类型,其行为类似于1行矩阵,但附加知识只有一行。它也是对原始矢量的懒惰“视图”。通过问题中的示例,这意味着size(b) == size(transpose(transpose(b)))
不仅是真的,还有b'' === b
。
在Julia 0.6中指定改变维度的重塑操作也更容易一些。上面问题2(创建nx1
数组)的一个很好的答案是reshape([1,2,3], :, 1)
。计算:
指定的维度以匹配源数组的长度。