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

时间:2017-10-30 18:20:41

标签: arrays tuples julia flatten

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

5 个答案:

答案 0 :(得分:10)

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

如果你有数组和元组数组的数组,你应该重新考虑你的数据结构,因为它听起来不稳定。但是,您可以使用多次调用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

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

答案 1 :(得分:7)

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

A = [[1,2,3],[4,5], [6,7]]
flat = [(A...)...]
println(flat)

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

答案 2 :(得分:5)

如果您使用here中的VectorOfArray,则会使用索引回退为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]

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

julia> VA[1,3]
7

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

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

处理此转换的另一种方法是执行hcat(A...)之类的操作,但是如果你有很多阵列在飞溅,那就太慢了!

现在,您可能会想:如何编写预先分配矩阵的函数,然后循环并填充它?这几乎是convert VectorOfArray的工作原理,除了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

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

答案 3 :(得分:3)

为了展平数组数组,你可以简单地使用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

答案 4 :(得分:0)

对于Julia 0.7x:

对于数组:

  

flat(arr :: Array)= mapreduce(x-> isa(x,Array)?flat(x):x,   append !, arr,init = [])

对于元组:

  

flat(arr :: Tuple)= mapreduce(x-> isa(x,Tuple)?flat(x):x,   append !, arr,init = [])

适用于任意深度。 参见:https://rosettacode.org/wiki/Flatten_a_list#Julia 数组/元组的代码:

function flatten(arr)
    rst = Any[]
    grep(v) =   for x in v
                if isa(x, Tuple) ||  isa(x, Array)
                grep(x) 
                else push!(rst, x) end
                end
    grep(arr)
    rst
end