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

时间:2017-04-30 23:23:33

标签: arrays julia

我的问题类似于earlier所描述的问题,  区别在于我没有手动输入数字。因此,那里接受的答案对我不起作用。

我想将笛卡尔坐标向量转换为极坐标:

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 个答案:

答案 0 :(得分:6)

如果你看一下cat的定义(这是hcatvcat的基础函数),你会看到你可以将几个数组收集到一个维度为2的单个数组中:

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

答案 1 :(得分: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元素数组(因为它返回的是什么)。然后这个调用就是mapslices(cart2pol, x, [2])。或者,如果我们真正想要表示的是坐标数组,则数据可以是元组[(x1,y1), (x2,y2), ...]的数组,cart2pol可以接受并返回元组。在任何一种情况下cart2pol都不需要能够在数组上运行,部分原因是我们已经弃用了@vectorize_宏。