Juliaでは、vec
は多次元配列を1次元配列に再形成します。ただし、配列の配列またはタプルの配列では機能しません。配列内包表記の使用の一部ですが、配列/タプルの配列をフラット化する別の方法はありますか?または、配列/配列のタプル/配列のタプル?または...
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}
を返すことに注意してください。これは、コンパイラが出力配列の要素の単一の具象型を決定できなかったことを意味するため、パフォーマンスの悪い兆候です。私がこれらの例を選んだのは、あなたの質問の読み方で、タイプが不安定なコンテナがすでにあるように思えたためです。
RecursiveArrayTools.jl からVectorOfArray
を使用する場合、インデックスフォールバックを使用してVectorOfArray
A
にconvert(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ですが、これは問題を解決するためのいくつかの方法です。
配列の配列をフラット化するには、次のように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
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