为什么在矩阵上使用`sum`函数返回的是矩阵而不是向量?

5

如果我这样做

mat = rand(8,8)
sum(mat, 1)

返回结果如下:

返回的类型是带有单行的矩阵,而sum(mat,2)给出了一个只有一列的矩阵。这让我感到惊讶,因为单例维度通常在0.5中被丢弃,所以我希望这两个操作的返回类型都是向量。为什么这里没有删除单例维度?

我可能会认为这是为了保留方向(例如,sum(mat,1)是一行向量),但在0.6上行为相同,该版本具有显式的1-D RowVectors,因此这似乎不是一个解释。

谢谢!

1个回答

4
是的,像 sum 这样的缩减操作会保留数组的维度。这是有意为之的,因为它可以使结果沿着原始数组进行广播。这意味着你可以使用 ./ 对数组的列进行归一化处理。
julia> A = rand(1:100, 4, 3)
4×3 Array{Int64,2}:
 94  50  32
 46  15  78
 34  29  41
 79  22  58

julia> A ./ sum(A, 1)
4×3 Array{Float64,2}:
 0.371542  0.431034  0.15311
 0.181818  0.12931   0.373206
 0.134387  0.25      0.196172
 0.312253  0.189655  0.277512

虽然二维情况可能可以使用RowVector来处理,但这种方法不能推广到更高的维度。

话虽如此,还有其他情况下降低维度会同样有用。这是一个关于问题跟踪器的开放设计问题


不错,谢谢!我确实考虑过广播,但没有想到它不能推广到更高的维度。我看到了问题,所以谢谢!这是因为我正在定义矩阵的行和列之和的函数,而将输入参数定义为“向量”似乎很自然,但这意味着我必须调用,例如myfunc(vec(sum(mat,1))),看起来很笨拙。但允许参数为矩阵似乎会引起问题。不过我想我可以通过分派来解决这个问题。 - Michael K. Borregaard
1
通常没有必要如此严格地限制参数类型。您几乎肯定可以使用AbstractVector代替Vector - 这将包括视图和重塑向量以及许多其他自定义向量类型。甚至常见的是扩展到所有维度,甚至到Any。当然,传递一些荒谬的东西可能会比您想象的晚一点出错,但它使某人能够传递类似于鸭子的东西,并且它仍然可以正常工作。 - mbauman
谢谢,我同意在函数参数(和重要的内部类型)中不通常需要限制类型,并且我喜欢这个原则!此外,我确实使用了AbstractVector(对于不清楚的地方很抱歉)。但是,在这种情况下,行矩阵和列矩阵与向量具有不同的行为(例如当传递给size等函数时),因此如果忽略维度,可能会导致意外的错误。最终,我做了一些类似于f(x::AbstractMatrix) = f(vec(x)); f(x::AbstractVector)...的事情。 - Michael K. Borregaard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接