Aus Raspberry Pi Geek 10/2020

Tabellenbearbeitung mit DataFrames (Seite 3)

Listing 10

> using CSV
> data = CSV.read("capitals.csv")
3x2 DataFrame
| Row | Land     | Hauptstadt |
|     | String   | String     |
+-----+----------+------------+
| 1   | Ägypten  | Kairo      |
| 2   | Albanien | Tirana     |
| 3   | Algerien | Algier     |
> data = copy(data);
> push!(data, ["Angola", "Luanda"])
4x2 DataFrame
| Row | Land     | Hauptstadt |
|     | String   | String     |
+-----+----------+------------+
| 1   | Ägypten  | Kairo      |
| 2   | Albanien | Tirana     |
| 3   | Algerien | Algier     |
| 4   | Angola   | Luanda     |
> CSV.write( "capitals.csv", data);

Die Funktion CSV.read() erwartet einen relativen oder absoluten Pfad zur CSV-Datei. Sie gibt einen unveränderlichen DataFrame zurück. Bei Bedarf erzeugen Sie per copy() eine veränderliche Kopie – etwa um, wie im Beispiel, eine weitere Zeile anzuhängen. Die modifizierte Tabelle speichern Sie genau wie jeden anderen DataFrame per CSV.write().

Tests und Experimente

Das Package RDatasets stellt 733 DataFrames mit Datensätzen aus jedem denkbaren Gebiet bereit. Ob Schmetterlingssichtungen in Malaysia, durch Pferdetritte verursachte Todesfälle, Dichtungsringfehler am Space Shuttle oder von Belgien aus geführte Überseetelefonate: Hier gibt es viele amüsante, kuriose und makabere Daten zu entdecken.

Listing 11 zeigt, wie Sie eine Aufstellung aller von RDatasets angebotenen DataFrames erhalten. Der Rückgabewert von RDatasets.datasets() ist selbst ein DataFrame, der zur vollen Darstellung ein rund 150 Zeilen breites Terminal benötigt. Die Funktion show() mit der Option allrows=true sorgt für die ungekürzte Darstellung der 733 Einträge.

Listing 11

> alldata = RDatasets.datasets();
> show(alldata, allrows=true)

Die Tabelle alldata hat fünf Spalten: Package steht für die Unterabteilung wie EcDat oder HistData; Dataset und Title speichern die Kurzbezeichnung und den Titel des Datensatzes, Rows und Columns die Anzahl der Spalten und Zeilen.

Der Iris-Datensatz

Im Folgenden schauen wir uns zwei geradezu klassische Datensätze genauer an. Der Iris-Datensatz wurde 1936 vom Biologen und Statistik-Pionier Ronald Fisher erstellt. Er enthält 150 Zeilen, von denen jede eine Schwertlilie repräsentiert. Die Spalten SepalLength, SepalWidth, PetalLength und PetalWidth stehen für die Länge und Breite der Kelch- und Blütenblätter. Die Daten lassen sich als eine Punktmenge in einem vierdimensionalen Raum interpretieren, wobei jeder Punkt eine Schwertlilie repräsentiert.

Die Spalte Species zeigt an, zu welcher der drei Arten die Pflanze gehört: setosa (Borsten-Schwertlilie), virginica (Virginische Schwertlilie) oder versicolor (verschiedenfarbige Schwertlilie).

Der Iris-Datensatz ist ein äußerst beliebtes Beispiel in Tutorials und Lehrbüchern über Statistik, Datenvisualisierung und KI. Trotz der überschaubaren Datenmenge und der wenigen Parameter lassen sich damit Verfahren des maschinellen Lernens demonstrieren, testen und vergleichen. Meist um anhand der Blattmaße die Zugehörigkeit zu einer Art mit größtmöglicher Treffsicherheit zu ermitteln.

Listing 12 lädt die Iris-Tabelle mittels der Funktion dataset(). Das erste Argument bezeichnet das Package, das zweite Argument den Datensatz. Die Funktion select() liefert dann eine auf die Spalten SepalLength, SepalWidth und Species reduzierte Tabelle.

Listing 12

> data = dataset("datasets", "iris")
150x5 DataFrame
| Row | SepalLength | SepalWidth | PetalLength | PetalWidth | Species |
|     | Float64     | Float64    | Float64     | Float64    | Cat...  |
+-----+-------------+------------+-------------+------------+---------+
| 1   | 5.1         | 3.5        | 1.4         | 0.2        | setosa  |
| 2   | 4.9         | 3.0        | 1.4         | 0.2        | setosa  |
| 3   | 4.7         | 3.2        | 1.3         | 0.2        | setosa  |
...
| 148 | 6.5         | 3.0        | 5.2         | 2.0        | virg... |
| 149 | 6.2         | 3.4        | 5.4         | 2.3        | virg... |
| 150 | 5.9         | 3.0        | 5.1         | 1.8        | virg... |
> data = select(data, :SepalLength, :SepalWidth, :Species)
150x3 DataFrame
| Row | SepalLength | SepalWidth | Species   |
|     | Float64     | Float64    | Cat...    |
+-----+-------------+------------+-----------+
| 1   | 5.1         | 3.5        | setosa    |
| 2   | 4.9         | 3.0        | setosa    |
| 3   | 4.7         | 3.2        | setosa    |
...
> sort!(data)
150x3 DataFrame
| Row | SepalLength | SepalWidth | Species    |
|     | Float64     | Float64    | Cat...     |
+-----+-------------+------------+------------+
| 1   | 4.3         | 3.0        | setosa     |
| 2   | 4.4         | 2.9        | setosa     |
| 3   | 4.4         | 3.0        | setosa     |
...
> sort!(data, :SepalWidth, rev=true)
150x3 DataFrame
| Row | SepalLength | SepalWidth | Species    |
|     | Float64     | Float64    | Cat...     |
+-----+-------------+------------+------------+
| 1   | 5.7         | 4.4        | setosa     |
| 2   | 5.5         | 4.2        | setosa     |
| 3   | 5.2         | 4.1        | setosa     |
...

Sortierungen erledigen Sie über die Funktion sort!(), wobei ein optionales zweites Argument die Spalte bestimmt, nach der die Funktion aufsteigend sortiert. Ohne Argument greift die erste Spalte. Mittels des Arguments rev=true schalten Sie auf absteigende Sortierung um.

Beachten Sie, dass viele Funktionen, die auf DataFrames arbeiten, in zwei Varianten vorliegen: sort!() und sort(), select!() und select() und so weiter. Die Versionen mit Ausrufezeichen verändern die im Argument übergebene Tabelle; jene ohne liefern eine modifizierte Tabelle zurück, während das Original unberührt bleibt.

Datensätze filtern

Über die Funktion filter() suchen Sie nach Datensätzen mit bestimmten Eigenschaften – etwa solche, bei denen der Wert für die Kelchblätter kleiner als 2,5 Millimeter ist. Die Funktion erwartet als erstes Argument wieder eine Funktion, die eine Tabellenzeile verarbeitet und true oder false zurückliefert – je nachdem, ob die Bedingung erfüllt ist oder nicht. Diese Rolle übernimmt in Listing 13 sepalwidth_less2_5().

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