刚刚玩Julia(1.0)并且我需要在Python/numpy/matlab中使用很多东西就是squeeze删除单例维度的功能.
我发现Julia的一种方法是:
a = rand(3, 3, 1);
a = dropdims(a, dims = tuple(findall(size(a) .== 1)...))
Run Code Online (Sandbox Code Playgroud)
第二行看起来有点麻烦,不容易阅读和解析(这也可能是我从其他语言带来的偏见).但是,我想知道这是否是在朱莉娅这样做的规范方式?
这个问题的实际答案让我感到惊讶.你问的问题可以改为:
为什么不
dropdims(a)删除所有单例尺寸?
我将从相关问题中引用Tim Holy :
不可能有挤压(A)返回编译器可以推断的类型 - 输入矩阵的大小是运行时变量,因此编译器无法知道输出将具有多少维度.所以它不可能给你你寻求的类型稳定性.
除了类型稳定性之外,还有其他一些令人惊讶的含义.例如,请注意:
julia> f(a) = dropdims(a, dims = tuple(findall(size(a) .== 1)...))
f (generic function with 1 method)
julia> f(rand(1,1,1))
0-dimensional Array{Float64,0}:
0.9939103383167442
Run Code Online (Sandbox Code Playgroud)
总之,在BaseJulia中包含这样的方法会鼓励用户使用它,从而导致潜在的类型不稳定的代码,在某些情况下,这些代码不会很快(核心开发人员正在努力避免这种情况).在像Python这样的语言中,不会强制执行严格的类型稳定性,因此您将找到这样的函数.
当然,没有什么可以阻止你定义自己的方法了.而且我认为你不会找到一种更简单的写作方式.例如,Base没有实现的建议是方法:
function squeeze(A::AbstractArray)
singleton_dims = tuple((d for d in 1:ndims(A) if size(A, d) == 1)...)
return squeeze(A, singleton_dims)
end
Run Code Online (Sandbox Code Playgroud)
请注意使用它的潜在影响.
让我简单地补充一下,“不受控制的” dropdims(删除任何单一维度)是错误的常见来源。例如,假设您有一些循环要求A从某个外部源获取数据数组,然后运行R = sum(A, dims=2)它,然后删除所有单例维度。但后来想,有一次出10000,你的外部源的回报A对于这size(A, 1)恰好是1:繁荣时期,你突然下降更多尺寸比你预期的,也许在为严重误解您的数据的风险。
如果您改为手动指定这些维度(例如,dropdims(R, dims=2)),那么您就可以免受此类错误的影响。
您可以删除tuple以支持逗号,:
dropdims(a, dims = (findall(size(a) .== 1)...,))
Run Code Online (Sandbox Code Playgroud)