Julia:展平数组/元组的数组

Pig*_*gna 8 arrays tuples flatten julia

在Julia中,vec将多维数组重新整形为一维数组.但是它不适用于数组数组或元组数组.使用数组理解的一部分,还有另一种方法来展平数组/元组的数组吗?还是数组/元组的数组/元组数组?要么 ...

小智 16

为了展平数组数组,您可以简单地使用 vcat() ,如下所示:

julia> A = [[1,2,3],[4,5], [6,7]]
Vector{Int64}[3]
    Int64[3]
    Int64[2]
    Int64[2]
julia> flat = vcat(A...)
Int64[7]
    1
    2
    3
    4
    5
    6
    7
Run Code Online (Sandbox Code Playgroud)

  • 似乎不适用于数组数组的数组。 (2认同)

Dáv*_*gga 12

最简单的方法是应用省略号...两次。

A = [[1,2,3],[4,5], [6,7]]
flat = [(A...)...]
println(flat)
Run Code Online (Sandbox Code Playgroud)

输出将是 [1, 2, 3, 4, 5, 6, 7].


ggg*_*ggg 11

Iterators.flatten(x)创建一个迭代每个元素的生成器x.它可以处理您描述的一些案例,例如

julia> collect(Iterators.flatten([(1,2,3),[4,5],6]))
6-element Array{Any,1}:
 1
 2
 3
 4
 5
 6
Run Code Online (Sandbox Code Playgroud)

如果你有数组和元组数组的数组,你应该重新考虑你的数据结构,因为它听起来不稳定.但是,您可以使用多个调用flatten,例如

julia> collect(Iterators.flatten([(1,2,[3,3,3,3]),[4,5],6]))
6-element Array{Any,1}:
 1            
 2            
  [3, 3, 3, 3]
 4            
 5            
 6            

julia> collect(Iterators.flatten(Iterators.flatten([(1,2,[3,3,3,3]),[4,5],6])))
9-element Array{Any,1}:
 1
 2
 3
 3
 3
 3
 4
 5
 6
Run Code Online (Sandbox Code Playgroud)

请注意我的所有示例如何返回Array{Any,1}.这对性能来说是个坏兆头,因为这意味着编译器无法为输出数组的元素确定单个具体类型.我之所以选择这些例子是因为我阅读你的问题的方式听起来像你可能已经有类型不稳定的容器了.

  • 现在已将`Iterators`内置到基础中,不赞成使用旧的`Iterators`软件包。我不知道如果现在安装它会发生什么,但是如果您有任何问题将其卸载。您需要使用Base.Iterators来获取导出的方法(包括flatten)或import Base.Iterators:flatten来获取一种方法。 (2认同)

Chr*_*kas 5

如果您使用VectorOfArrayRecursiveArrayTools.jl,它使用索引回落提供convert(Array,A)了一个VectorOfArray A.

julia> using RecursiveArrayTools

julia> A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
3-element Array{Array{Int64,1},1}:
 [1, 2, 3]
 [4, 5, 6]
 [7, 8, 9]

julia> VA = VectorOfArray(A)
3-element Array{Array{Int64,1},1}:
 [1, 2, 3]
 [4, 5, 6]
 [7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

首先它充当一个惰性包装器,用于在不转换的情况下进行索引:

julia> VA[1,3]
7
Run Code Online (Sandbox Code Playgroud)

请注意,列是单独的数组,因此它仍然是"列主要"(即有效地索引列).但它有一个直接的转换:

julia> convert(Array,VA)
3×3 Array{Int64,2}:
 1  4  7
 2  5  8
 3  6  9
Run Code Online (Sandbox Code Playgroud)

处理这种转换的另一种方法是做类似的事情hcat(A...),但是如果你有很多阵列你正在喷溅那么这很慢!

现在,您可能会想:如何编写预先分配矩阵的函数,然后循环并填充它?这几乎就是convertVectorOfArray工作中,除了convert这里使用的后备利用Tim Holy的笛卡尔机器.有一次,我写了这个函数:

function vecvec_to_mat(vecvec)
  mat = Matrix{eltype(eltype(vecvec))}(length(vecvec),length(vecvec[1]))
  for i in 1:length(vecvec)
    mat[i,:] .= vecvec[i]
  end
  mat
end
Run Code Online (Sandbox Code Playgroud)

但是我已经摆脱它了,因为后退要快得多.所以,YMMV,但这是解决问题的几种方法.