web-dev-qa-db-ja.com

ジュリア:配列/タプルの配列のフラット化

Juliaでは、vecは多次元配列を1次元配列に再形成します。ただし、配列の配列またはタプルの配列では機能しません。配列内包表記の使用の一部ですが、配列/タプルの配列をフラット化する別の方法はありますか?または、配列/配列のタプル/配列のタプル?または...

11
Pigna

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}を返すことに注意してください。これは、コンパイラが出力配列の要素の単一の具象型を決定できなかったことを意味するため、パフォーマンスの悪い兆候です。私がこれらの例を選んだのは、あなたの質問の読み方で、タイプが不安定なコンテナがすでにあるように思えたためです。

11
gggg

RecursiveArrayTools.jl からVectorOfArrayを使用する場合、インデックスフォールバックを使用してVectorOfArrayAconvert(Array,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
_

この変換を処理するもう1つの方法は、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ですが、これは問題を解決するためのいくつかの方法です。

5

配列の配列をフラット化するには、次のように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
aggharta

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
0
Ultima Ratio