Elemente auslesen
Die Funktion names() liefert ein Array mit den Bezeichnern der Spalten. Die Funktion size() gibt, wie bei allen Array-artigen Typen, die Dimensionen als Tupel zurück (Listing 5).
Listing 5
> data = DataFrame(A=1:4, B=5:8) 4x2 DataFrame | Row | A | B | | | Int32 | Int32 | +-----+-------+-------+ | 1 | 1 | 5 | | 2 | 2 | 6 | | 3 | 3 | 7 | | 4 | 4 | 8 | > names(data) 2-element Array{String,1}: "A" "B" > size(data) (4, 2)
Der Zugriff auf DataFrames ähnelt oft dem auf ein zweidimensionales Array. So sprechen Sie einzelne Elemente oder Bereiche mit Ausdrücken wie data[X, Y] oder data[1:2, :] an. Dieses Vorgehen dürfte aber nur in seltenen Fällen sinnvoll sein, weil Sie dabei die Vorteile des Adressierens über die Bezeichner der Spalten nicht nutzen.
Sie dürfen Spalten gleichwertig per String oder Symbol adressieren. Listing 6 zeigt drei im Ergebnis identische Ausdrücke, die die Spalte A als Array zurückgeben. Beachten Sie, dass diese Ausdrücke eine Referenz auf A liefern, Modifikationen also den Inhalt der ursprünglichen Tabelle ändern. Der Ausdruck data[:, :B] hingegen liefert eine von der Tabelle unabhängige Kopie. Daher ändert in diesem Fall die Zuweisung nicht den Wert in data.
Listing 6
> data.A 4-element Array{Int32,1}: 1 2 3 4 > data[!, :A] ... > data[!, "A"] ... > data[!, :A][1] = 23; > data 4x2 DataFrame | Row | A | B | | | Int64 | Int64 | +-----+-------+-------+ | 1 | 23 | 5 | | 2 | 2 | 6 | ... > data[:, :B][2] = 42; > data 4x2 DataFrame | Row | A | B | | | Int64 | Int64 | +-----+-------+-------+ | 1 | 23 | 5 | | 2 | 2 | 6 | ...
Mit der Funktion eachcol() iterieren Sie über die Spalten eines DataFrames (Listing 7). Listing 8 zeigt den Zugriff auf einzelne Zeilen, die Sie über den bereits erwähnten Datentyp DataFrameRow ansprechen. Er bietet die Möglichkeit, über die Bezeichner der Spalten auf die einzelnen Elemente zuzugreifen. Dabei ist sowohl die Punkt- als auch Indexnotation erlaubt. Analog zu eachcol() iterieren Sie per eachrow() über die Zeilen.
Listing 7
> data = DataFrame(A=1:6, B='a':'f') 6x2 DataFrame | Row | A | B | | | Int32 | Char | +-----+-------+------+ | 1 | 1 | 'a' | | 2 | 2 | 'b' | | 3 | 3 | 'c' | ... > for col in eachcol(data) println(col) end [1, 2, 3, 4, 5, 6] ['a', 'b', 'c', 'd', 'e', 'f']
Listing 8
> data = DataFrame( NAME=["Alice", "Bob"], ALTER=[42, 27], HOBBY=["malen", "lesen"]) 2x3 DataFrame | Row | NAME | ALTER | HOBBY | | | String | Int32 | String | +-----+--------+-------+--------+ | 1 | Alice | 42 | malen | | 2 | Bob | 27 | lesen | > bob = data[2, :] DataFrameRow | Row | NAME | ALTER | HOBBY | | | String | Int32 | String | +-----+--------+-------+--------+ | 2 | Bob | 27 | lesen | > bob[:HOBBY] "lesen" > bob.ALTER 27 > for row in eachrow(data) println("Name: ", row.NAME) println("Hobby: ", row.HOBBY) end Name: Alice Hobby: malen Name: Bob Hobby: lesen
Fehlende Daten
Ob defekte Messfühler, unvollständig ausgefüllte Formulare oder das Zusammenführen heterogen formatierter Datensätze im Rahmen von Metastudien: In der realen Welt gibt es viele Ursachen für unvollständige Daten. Dieser Tatsache wird Julia mit dem Datentyp Missing und seinem einzigen Vertreter missing gerecht.
Die Spalte A vom Typ Any (Listing 9) akzeptiert ohne Weiteres Einträge vom Typ Missing. Bei präziser typisierten Spalten ist es dagegen nötig, die Aufnahme fehlender Werte explizit zuzulassen. In Listing 9 setzt die Funktion allowmissing!() dieses Recht für die gesamte Tabelle – mit einem zweiten Argument gelingt das für eine bestimmte Spalte. Die Typbezeichnung von Spalte B – Int32? – signalisiert anschließend per angehängtem Fragezeichen, dass diese nun fehlende Werte enthalten darf.
Listing 9
> data = DataFrame(A=[], B=Int[]); > push!(data, [missing, 1]) 1x2 DataFrame | Row | A | B | | | Any | Int32 | +-----+---------+-------+ | 1 | missing | 1 | > push!(data, [1, missing]) ERROR: MethodError: Cannot `convert` an object of type Missing to an object of type Int32 > allowmissing!(data); > push!(data, [1, missing]) 2x2 DataFrame | Row | A | B | | | Any | Int32? | +-----+---------+---------+ | 1 | missing | 1 | | 2 | 1 | missing | > typeof(data.B) Array{Union{Missing, Int64},1}
Nebenbei bemerkt: Die Ausgabe von typeof(data.B) zeigt einen Union-Typ an. Neben den in Teil 2 der Julia-Einführung [3] vorgestellten abstrakten Basistypen sind Union-Typen eine alternative Möglichkeit, unterschiedliche Typen zur gemeinschaftlichen Behandlung zusammenzufassen.
Speichern und Laden
Julia stellt über Packages wie CSV oder SQLite Schnittstellen zu diversen Formaten für Dateien und Datenbanken bereit. Wir beschränken uns hier auf ein einfaches Beispiel, den Im- und Export von CSV-Dateien (Listing 10).





