Aus Raspberry Pi Geek 10/2020

Tabellenbearbeitung mit DataFrames

© Jill Battaglia, 123RF

In Reih und Glied

Pit Noack

Mit dem Paket DataFrames verarbeiten Sie in der Programmiersprache Julia auf einfache Weise tabellarische Daten.

Die Programmiersprache Julia [1] empfiehlt sich zum Bearbeiten von Daten aus wissenschaftlichen Versuchen. Diese liegen oft in Form von Tabellen vor oder landen nach einer Versuchsreihe in einer solchen. Julia ist in der Lage, Daten in diesem Format zu verarbeiten, anzuzeigen und zu speichern. Haben Sie keine entsprechenden Datensätze für Tests zur Hand, liefert das Julia-Package RDatasets eine Fülle an Beispielen aus vielen Bereichen. Für die erste Installation braucht es aber vor allem Geduld (siehe Kasten “Voraussetzungen”).

Voraussetzungen

Dieser Artikel setzt Julia-Grundkenntnisse und eine entsprechende Installation [2] voraus, wie wir sie in den ersten Teilen dieser Serie [3] gezeigt haben. Aktuell ist Julia 1.4, das neueste Binary für 32-Bit-Systeme der ARM-Plattform steht im Moment noch bei Version 1.3. Da die Installation und das erstmalige Einbinden von Packages auf dem RasPi einige Zeit in Anspruch nimmt, empfiehlt es sich, das Listing 1 zu Beginn einmal auszuführen und in der Zeit ein Getränk der Wahl zu genießen.

Listing 1

using Pkg
Pkg.add("DataFrames")
Pkg.add("RDatasets")
Pkg.add("PyPlot")
Pkg.add("Statistics")
Pkg.add("CSV")
using DataFrames
using RDatasets
using PyPlot
using Statistics
using CSV

Package <I>DataFrames<I>

Mit dem Package DataFrames stellt Julia eine Reihe Datentypen und Funktionen bereit, die den flexiblen Umgang mit tabellarischen Daten erlauben. Im Zentrum steht der gleichnamige Typ DataFrame, der Tabellen repräsentiert. Die bestehen aus Zeilen (Rows) und Spalten (Columns). Jede Spalte sprechen Sie über einen Namen an. In ihr speichert die Software ein eindimensionales Array.

Listing 2 demonstriert, wie Sie über den Aufruf des Konstruktors einen DataFrame erzeugen. Das Listing zeigt, dass Sie sowohl eindimensionale Arrays als auch UnitRanges wie 1:3 oder 'a':'c' zum Befüllen der Spalten verwenden dürfen.

Listing 2

> using DataFrames
> DataFrame(A=[3,5,7])
3x1 DataFrame
| Row | A     |
|     | Int32 |
+-----+-------+
| 1   | 3     |
| 2   | 5     |
| 3   | 7     |
> DataFrame(A=1:3, B='a':'c')
3x2 DataFrame
| Row | A     | B    |
|     | Int32 | Char |
+-----+-------+------+
| 1   | 1     | 'a'  |
| 2   | 2     | 'b'  |
| 3   | 3     | 'c'  |
> DataFrame(A=[23,3.14])
2x1 DataFrame
| Row | A       |
|     | Float64 |
+-----+---------+
| 1   | 23.0    |
| 2   | 3.14    |

Die Überschriften zeigen den Typ der jeweiligen Spalte an. Julia folgert – wie beim Initialisieren von Arrays üblich – den gemeinsamen Typ der enthaltenen Elemente automatisch. Für [23, 3.14] ist es Float64, für [42, "x"] wäre es der Typ Any.

Anhängen und einfügen

Bei Bedarf beginnen Sie mit einer leeren Tabelle und legen lediglich deren Formatierung fest, also die Anzahl, Namen und Typisierungen der Spalten. Listing 3 baut nach diesem Muster eine Tabelle für Sinuswerte zusammen.

Listing 3

> sinvals = DataFrame(X=Float64[], SINX=Float64[])
0x2 DataFrame
> for x in 0:0.01:2*pi
    push!(sinvals, [x, sin(x)])
  end
> sinvals
692x2 DataFrame
| Row | X       | SINX       |
|     | Float64 | Float64    |
+-----+---------+------------+
| 1   | 0.0     | 0.0        |
| 2   | 0.1     | 0.0998334  |
| 3   | 0.2     | 0.198669   |
...

Die erste Eingabe erzeugt eine leere Tabelle sinvals mit den Spalten X und SINX, beide vom Typ Float64. Anschließend füllt eine For-Schleife die Tabelle mit Werten. Dabei kommt die Funktion push!() zum Einsatz. Die Anzahl und der Typ der Elemente des im zweiten Argument übergebenen Arrays müssen dem Format der Tabelle entsprechen. Sie dürfen push!() statt eines Arrays auch ein Tupel, ein NamedTupel, ein Dict oder eine DataFrameRow übergeben.

Das nachträgliche Einfügen von Spalten gelingt mittels insertcols!() (Listing 4). Sie übergeben der Funktion eine oder mehrere Spalten in Form von Schlüssel-Wert-Paaren (Typ Pair). Diese Notation funktioniert übrigens auch bei Konstruktoraufrufen von DataFrame.

Listing 4

> data = DataFrame()
0x0 DataFrame
> insertcols!(data, :A=>[1,2,3])
3x1 DataFrame
| Row | A     |
|     | Int32 |
+-----+-------+
| 1   | 1     |
| 2   | 2     |
| 3   | 3     |
> insertcols!(data, :B=>[0,0])
ERROR: DimensionMismatch("length of new column B which is 2 must match the number of rows in data frame")
> insertcols!(data, :B=>0)
3x2 DataFrame
| Row | A     | B     |
|     | Int32 | Int32 |
+-----+-------+-------+
| 1   | 1     | 0     |
| 2   | 2     | 0     |
| 3   | 3     | 0     |
> insertcols!(data, 1, :FIRST=>1)
3x3 DataFrame
| Row | FIRST | A     | B     |
|     | Int32 | Int32 | Int32 |
+-----+-------+-------+-------+
| 1   | 1     | 1     | 0     |
| 2   | 1     | 2     | 0     |
| 3   | 1     | 3     | 0     |

Ist ein DataFrame nicht leer, dann muss die Anzahl der Elemente in der hinzugefügten Spalte jener in den bereits vorhandenen Spalten entsprechen. Gegebenenfalls füllen Sie alle Zeilen einer neuen Spalte mit einem einzelnen Wert. Ohne weitere Angaben hängt insertcols!() die Spalten rechts an. Mittels eines optionalen zweiten, ganzzahligen Arguments bestimmen Sie bei Bedarf die Position der neuen Spalte.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 7 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben