在Julia中将Array{Array{Float64,1},1}转换为Array{Float64,2}

3
我的问题类似于之前描述的问题,链接如下:链接,不同之处在于我不是手动输入数字。因此,那里接受的答案对我不起作用。
我想将笛卡尔坐标向量转换为极坐标:
function cart2pol(x0,
                  x1)
    rho = sqrt(x0^2 + x1^2)
    phi = atan2(x1, x0)
    return [rho, phi]
end

@vectorize_2arg Number cart2pol

function cart2pol(x)
    x1 = view(x,:,1)
    x2 = view(x,:,2)
    return cart2pol(x1, x2)
end



x = rand(5,2)

vcat(cart2pol(x))

由于某些原因,最后一个命令未收集数组,返回类型为5-element Array{Array{Float64,1},1}的输出。有什么办法可以将其转换为Array{Float64,2}吗?


2
你链接的问题中的答案应该能够正常工作。你只需要 splat 数组的数组: hcat(cart2pol(x)...)vcat(map(transpose, cart2pol(x))...)。那些三个点很重要。 - mbauman
2个回答

6

如果您查看cat的定义(它是hcatvcat的基础函数),您会发现可以将多个数组收集到一个二维数组中:

cat(2, [1,2], [3,4], [5,6])

2×3 Array{Int64,2}:
 1  3  5
 2  4  6

这基本上是您想要的。问题在于您所有的输出极点都在一个数组中。但是cat希望您将它们提供为几个参数。这就是...的作用。

在函数调用的上下文中使用...使单个函数参数分解为多个不同的参数。

因此,您可以这样编写:
cat(2, [[1,2], [3,4], [5,6]]...)

2×3 Array{Int64,2}:
 1  3  5
 2  4  6

在你的情况下,它的工作方式完全相同(我更改了你的x以使点在列中):
x=rand(2,5)
cat(2, cart2pol.(view(x,1,:),view(x,2,:))...)

2×5 Array{Float64,2}:
 0.587301  0.622    0.928159  0.579749  0.227605
 1.30672   1.52956  0.352177  0.710973  0.909746

2
我们真的应该有一个不需要使用 splatting 的函数来完成这个操作;因此,我已经打开了一个问题:https://github.com/JuliaLang/julia/issues/21672。 - StefanKarpinski

4
函数mapslices也可以实现这一点,本质上是转换输入的行:
julia> x = rand(5,2)
5×2 Array{Float64,2}:
 0.458583   0.205246 
 0.285189   0.992547 
 0.947025   0.0853141
 0.79599    0.67265  
 0.0273176  0.381066 

julia> mapslices(row->cart2pol(row[1],row[2]), x, [2])
5×2 Array{Float64,2}:
 0.502419  0.420827 
 1.03271   1.291    
 0.95086   0.0898439
 1.04214   0.701612 
 0.382044  1.49923  

最后一个参数指定要操作的维度;例如,传递[1]会转换列。
另外,我建议进行一到两个风格上的更改。首先,将其映射到相应位置是很好的,因此如果我们坚持使用行表示,则cart2pol应该接受一个2元素数组(因为它返回2个元素)。然后,这个调用将变成mapslices(cart2pol, x, [2])。或者,如果我们真正想要表示的是一个坐标数组,那么数据可以是元组数组[(x1,y1),(x2,y2),...],而cart2pol可以接受和返回元组。在任何情况下,cart2pol不需要能够操作数组,正是因为这个原因,我们已经弃用了@vectorize_宏。

+1 我认为我的答案已经包含了使cart2pol一致(或者像你说的那样"映射到相似的类型")。当你有一个函数将一个坐标系转换为另一个坐标系,并且它接受一个元组并输出一个数组时,这看起来并不好看。 - halirutan
同意,我会将两个元组或两个数组都进行处理。我认为在将来,我们也可以通过允许在正式参数中使用元组解构来改善情况,例如:function cart2pol((x0,x1)) ... return (rho,phi) end,这样参数和返回值看起来更相似。 - Jeff Bezanson

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