2017-10-30 3 views
2

In Julia vec umformt mehrdimensionale Arrays in eindimensionale Arrays. Allerdings funktioniert es nicht für Arrays von Arrays oder Arrays von Tupeln. Ein Teil von Array Verständnis, gibt es eine andere Möglichkeit, Arrays von Arrays/Tupel zu reduzieren? Oder Arrays von Arrays/Tupeln von Arrays/Tupeln? Oder ...Julia: Abflachen Array von Array/Tupel

Antwort

5

Iterators.flatten(x) erstellt einen Generator, der über jedes Element von x iteriert. Es kann einige der Fälle behandeln Sie zB

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

beschreiben Wenn Sie Arrays von Arrays von Arrays und Tupel haben, sollten Sie wahrscheinlich Ihre Datenstruktur überdenken, weil sie nicht stabil Typ klingt. Sie können jedoch mehrere Anrufe zu flatten, zB

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 

Hinweis verwenden, wie alle meine Beispiel eine Array{Any,1} zurück. Das ist ein schlechtes Zeichen für die Leistung, weil es bedeutet, dass der Compiler keinen einzelnen konkreten Typ für die Elemente des Ausgabearrays bestimmen konnte. Ich habe dieses Beispiel gewählt, weil die Art und Weise, wie ich Ihre Frage gelesen habe, so klingt, als hätten Sie bereits instabile Container eingegeben.

+0

Das ist genau das, was ich gesucht habe! In meinem Fall sind es nur Arrays, keine Tupel, also ist es nicht mein Problem. Nach dem Hinzufügen des "Iterators" -Pakets und dem Aufruf von "Iteratoren", wenn ich flatten versuche (innerhalb der REPL), sagt es mir, dass die Funktion nicht existiert. Ich bin auf Julia 0.6.1 – Pigna

+1

'Iterators' ist jetzt eingebaut base ist das alte 'Iterators'-Paket veraltet. Ich weiß nicht, was passiert, wenn Sie es jetzt installieren, aber wenn Sie irgendwelche Probleme haben, deinstallieren Sie es. Sie müssen 'Base.Iterators' verwenden, um die exportierten Methoden (einschließlich' flatten') oder 'importBase.Iterators: flatten' zu erhalten, um nur einen zu erhalten. – gggg

4

Wenn Sie VectorOfArray von RecursiveArrayTools.jl, verwendet es die Indizierung Ausweich convert(Array,A) für eine VectorOfArrayA bereitzustellen.

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] 

Zunächst wirkt sie als faul Wrapper für das Erledigen der Indizierung ohne Konvertierung:

julia> VA[1,3] 
7 

Beachten Sie, dass Spalten sind die einzelnen Felder, so dass die Art und Weise ist es immer noch „column-major“ (dh effizient Spalten nach unten). Aber dann hat es eine gerade Umwandlung:

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

Der andere Weg, um diese Umwandlung zu handhaben ist so etwas wie hcat(A...) zu tun, aber das ist langsam, wenn Sie eine Menge von Arrays haben Sie Splatting!

Nun denken Sie vielleicht: Was ist mit dem Schreiben einer Funktion, die die Matrix vorverteilt, dann durchläuft und füllt es? Das ist fast das, was convert auf dem VectorOfArray funktioniert, außer dem Fallback, dass convert hier verwendet Tim Holy's Cartesian Maschinerie verwendet. An einem Punkt, schrieb ich diese Funktion:

aber ich habe seit es losgeworden, weil der Fallback viel schneller war. Also, YMMV, aber das sind ein paar Möglichkeiten, um Ihr Problem zu lösen.

2

Um ein Array von Arrays zu glätten, können Sie einfach VCAT() wie folgt verwenden:

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 
+0

Scheint nicht für Arrays von Arrays von Arrays zu funktionieren. – Timmmm

Verwandte Themen