Julia 中如何在不同类型的多维数组之间进行转换

Pro*_*ala 4 arrays multidimensional-array julia

我正在从 python/numpy 迁移到 julia。我真的对 Julia 的多维数组感到困惑,感觉有一些额外的复杂性/麻烦(与 numpy 相比)。

\n\n

1) 行向量、2) 列向量、3) 多维数组和 4) 嵌套数组(=数组的数组)之间存在区别。假设有一种简单的方法可以在它们之间进行转换,那就没问题了(也许对性能优化有用)。但我不知道该怎么做。

\n\n

简单的例子: \n我只是尝试生成点的二维矩形网格并绘制它们

\n\n
\nps = [ [ix*0.1 iy*0.1] for ix=1:10, iy=1:10 ]\n# 10\xc3\x9710 Array{Array{Float64,2},2}:\n# Oh, this is nested array? I wand just simple 3D array 10x10x2\n\nscatter( ps[:,:,1], ps[:,:,2], markersize = 2, markerstrokewidth = 0, aspect_ratio=:equal )\n# ERROR: BoundsError: attempt to access 10\xc3\x9710 Array{Array{Float64,2},2} at index [Base.Slice(Base.OneTo(10)), Base.Slice(Base.OneTo(10)), 2]\n\nsh = size(ps)\n# (10,10)\n\nps = reshape( ps, ( sh[1]*sh[2],2) )\n# ERROR: DimensionMismatch("new dimensions (100, 2) must be consistent with  array size 100")\n# Oh dear :(\n\nps = reshape( ps, ( sh[1]*sh[2],:) )\n# 100\xc3\x971 Array{Array{Float64,2},2}\n\nxs = ps[:,1]\n# 100-element Array{Array{Float64,2},1}\n# ??? WTF? ... this arrays looks like whole \'ps\' \nys = ps[:,2] \n# ERROR: BoundsError: attempt to access 100\xc3\x971 Array{Array{Float64,2},2} at index [Base.Slice(Base.OneTo(100)), 2]\n\nxs = ps[:][1]\n# 1\xc3\x972 Array{Float64,2}: \n#  0.1  0.1\n#  But I want all xs  (ps[:,1]), not (ps[1,:]) \n\n# Let\'s try some broadcasting\nxs = ps.[1]\n# ERROR: syntax: invalid syntax "ps.[1]"\nxs = .ps[1]\n# ERROR: syntax: invalid identifier name "."\n\n\n# Perhaps transpose will help?\nps_ = ps\'   #\' stackoverflow syntax highlighting for Julia is broken ?\n# 1\xc3\x97100 LinearAlgebra.Adjoint{LinearAlgebra.Adjoint{Float64,Array{Float64,2}},Array{Array{Float64,2},2}}:\n# OMG! ... That is even worse\n\nscatter( ps[:,1], ps[:,2], markersize = 2, markerstrokewidth = 0, aspect_ratio=:equal )\n# Nope\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

好吧,这有点有效。但我仍然需要弄清楚如何在上面的不同形状的数组之间进行转换

\n\n
using Plots\nps = [ [ix*0.1 iy*0.1] for ix=1:10, iy=1:10 ]\nps = vcat(ps...)\nxs = ps[:,1]\nys = ps[:,2]\nscatter( xs, ys, markersize = 2, markerstrokewidth = 0, aspect_ratio=:equal )\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑:

\n\n

也许最好列出一些我在提问之前搜索答案的教程:

\n\n\n

Jef*_*off 5

Julia 以列优先方式工作,因此基本向量是列向量。\n要将列向量转换为行向量,请使用permutedims(colvec)。\n要将行向量转换为列向量,请使用permutedims(rowvec)

\n\n
julia> colvec = [1, 2, 3]\n3-element Array{Int64,1}:\n 1\n 2\n 3\n\njulia> rowvec = permutedims(colvec)\n1\xc3\x973 Array{Int64,2}:\n 1  2  3\n\njulia> permutedims(rowvec)\n3\xc3\x971 Array{Int64,2}:\n 1\n 2\n 3\n
Run Code Online (Sandbox Code Playgroud)\n\n

要将矩阵(或任何二维数组)转换为列向量,请使用vec。因为 Julia 按列存储二维数组,所以这将依次遍历每一列。请注意,二维数组维度显示为<rows>x<cols> Array{<type>,2}

\n\n
julia> matrix = [1 4 \n                 2 5 \n                 3 6]\n3\xc3\x972 Array{Int64,2}:\n 1  4\n 2  5\n 3  6  \n\njulia> colvec = vec(matrix)\n6-element Array{Int64,1}:\n 1\n 2\n 3\n 4\n 5\n 6\n
Run Code Online (Sandbox Code Playgroud)\n\n

要将其转换colvec回原始数组需要知道原始数组的维度。ndims(x)计算 x 的维度并size(x)给出 x 的每个维度中的元素数量。

\n\n
julia> reshape(colvec, size(matrix))\n3\xc3\x972 Array{Int64,2}:\n 1  4\n 2  5\n 3  6\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以使用 转置条目permutedims(matrix)

\n\n
julia> matrix\n3\xc3\x972 Array{Int64,2}:\n 1  4\n 2  5\n 3  6\n\njulia> permutedims(matrix)\n2\xc3\x973 Array{Int64,2}:\n 1  2  3\n 4  5  6\n
Run Code Online (Sandbox Code Playgroud)\n\n

同样的原理也适用于更高维的数组。

\n\n
array = reshape(collect(1:12), (3, 2, 2))\n3\xc3\x972\xc3\x972 Array{Int64,3}:\n[:, :, 1] =\n 1  4\n 2  5\n 3  6\n\n[:, :, 2] =\n 7  10\n 8  11\n 9  12\n\njulia> vec(array)\n12-element Array{Int64,1}:\n  1\n  2\n  3\n  4\n  5\n  6\n  7\n  8\n  9\n 10\n 11\n 12\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于使用嵌套数组,我建议使用RecursiveArrayTools.jl

\n