Dans Julia vec
remodèle les tableaux multidimensionnels en tableaux à une dimension. Cependant, cela ne fonctionne pas pour les tableaux de tableaux ou les tableaux de tuples. En plus d'utiliser la compréhension des tableaux, existe-t-il une autre façon d'aplatir les tableaux de tableaux/tuples? Ou des tableaux de tableaux/tuples de tableaux/tuples? Ou ...
Iterators.flatten(x)
crée un générateur qui itère sur chaque élément de x
. Il peut gérer certains des cas que vous décrivez, par exemple
Julia> collect(Iterators.flatten([(1,2,3),[4,5],6]))
6-element Array{Any,1}:
1
2
3
4
5
6
Si vous avez des tableaux de tableaux de tableaux et de tuples, vous devriez probablement reconsidérer votre structure de données car elle ne semble pas de type stable. Cependant, vous pouvez utiliser plusieurs appels à flatten
, par exemple
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
Notez comment tous mes exemples retournent un Array{Any,1}
. C'est un mauvais signe pour les performances, car cela signifie que le compilateur n'a pas pu déterminer un seul type concret pour les éléments du tableau de sortie. J'ai choisi ces exemples parce que la façon dont j'ai lu votre question, il semblait que vous ayez peut-être déjà des conteneurs instables de type.
Si vous utilisez VectorOfArray
de RecursiveArrayTools.jl , il utilise le repli d'indexation pour fournir convert(Array,A)
pour un 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]
Le premier agit comme un wrapper paresseux pour faire l'indexation sans conversion:
Julia> VA[1,3]
7
Notez que les colonnes sont des tableaux séparés, de sorte que c'est toujours "majeur de colonne" (c'est-à-dire efficace pour indexer les colonnes). Mais alors il a une conversion directe:
Julia> convert(Array,VA)
3×3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
L'autre façon de gérer cette conversion est de faire quelque chose comme hcat(A...)
, mais c'est lent si vous avez beaucoup de tableaux que vous éclaboussez!
Maintenant, vous pouvez penser: qu'en est-il de l'écriture d'une fonction qui pré-alloue la matrice, puis la boucle et la remplit? C'est presque ce que convert
sur le VectorOfArray
fonctionne, sauf que la solution de repli que convert
utilise ici utilise la machinerie cartésienne de Tim Holy. À un moment donné, j'ai écrit cette fonction:
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
mais je m'en suis débarrassé depuis car le repli a été beaucoup plus rapide. Donc, YMMV mais c'est quelques façons de résoudre votre problème.
Afin d'aplatir un tableau de tableaux, vous pouvez simplement utiliser vcat () comme ceci:
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
pour Julia 0.7x:
pour les tableaux:
flat (arr :: Array) = mapreduce (x -> isa (x, Array)? flat (x): x, append !, arr, init = [])
pour Tuples:
flat (arr :: Tuple) = mapreduce (x -> isa (x, Tuple)? flat (x): x, append !, arr, init = [])
Fonctionne pour une profondeur arbitraire. voir: https://rosettacode.org/wiki/Flatten_a_list#Julia Code pour tableau/tuple:
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