Die Ingenieurs-Mailbox
Folge 4: Pythons und Pandas, oh je!

Hin und wieder stoßen wir Systemingenieure auf interessante Fragestellungen, die etwas außerhalb des typischen Anwendungsbereichs von JMP liegen. Diese Anwendungen sind meist raffiniert und verdeutlichen oft, dass die Nutzung von Daten nicht auf die Lösung geschäftlicher oder technischer Probleme beschränkt ist. Manchmal handelt es sich aber auch einfach um unerwartete, herausfordernde Probleme. Diese „Überraschungsmomente“ (wie ich sie gerne nenne) treten in vielfältiger Form auf: Programmierprobleme, interessante Analysen, Möglichkeiten zur Datenvisualisierung … Sie verstehen, was ich meine.
Ich habe schon länger nichts mehr aus dem Briefkasten geschrieben, aber diese Frage schien mir wirklich wichtig genug, um beantwortet zu werden. Das Tool, mit dem ich die Frage beantwortet habe, wird meiner Meinung nach viel zu selten besprochen. Daher möchte ich hier einem Kollegen aus New York helfen und allen eine interessante Funktion von JMP zeigen, die Ihnen vielleicht noch unbekannt ist.
Die Frage
Mike[JMP],
Oft muss ich groupby-Operationen durchführen, um beispielsweise den Maximalwert aller Werte, gruppiert nach einem bestimmten Label, zu ermitteln. Das entsprechende Python-Pandas-Äquivalent sähe etwa so aus:
df.groupby(['Something', 'Something Else']).max()
Eine andere Möglichkeit wäre beispielsweise pandas.nlargest mit einer groupby-Klausel, wobei ich beispielsweise die Top 5 der Ergebnisse aus der groupby-Klausel erhalten möchte.
Nach ein paar Minuten Herumprobieren mit einer Spaltenformel gebe ich auf und exportiere die Daten, um sie später wieder in JMP zu importieren. Die Funktion „Tabulate“ kann das zwar auch, aber nicht immer so, wie ich es mir wünsche. Ein Dokument mit dem Titel „JMP wie Pandas nutzen“ wäre daher äußerst hilfreich für mich und könnte angesichts der weiten Verbreitung von Pandas auch für JMP selbst nützlich sein.
Danke,
Nick
Meine Antwort
Hallo Nick! Es gibt einen Trick, mit dem Sie Formeln flexibler gestalten können und der viele Funktionen von Pandas nachahmt. Dazu geben Sie JMP an, nach welchen Spalten gruppiert werden soll. Klicken Sie dazu mit der rechten Maustaste auf den Spaltennamen und wählen Sie „Neue Formelspalte“ > „Gruppieren nach“.

Anschließend werden alle Formelspalten, die Sie durch Rechtsklick auf den Spaltennamen und anschließendes Auswählen von „Neue Formelspalte > …“ erstellen, nach den von Ihnen festgelegten Gruppierungsspalten gruppiert.


Danach müssen Sie nur noch die Daten mithilfe von Datenfiltern oder lokalen Datenfiltern filtern oder Teilmengen erstellen. Lassen Sie mich wissen, ob Ihnen das weiterhilft!
Am besten,
M
Pandas: Niedliche Marderartige oder Datenanalyse-Tools?
Okay, für alle, die Pandas noch nicht kennen: Pandas ist kein knuddeliger, farblich eingeschränkter Marder. Pandas (in Python-Skripten meist als „pd“ abgekürzt) ist eine Python-Programmiersprache zur Datenmanipulation und -analyse. Sie bietet insbesondere Datenstrukturen und Operationen zur Bearbeitung numerischer Tabellen und Zeitreihen [ Quelle ].“ Im Grunde übernimmt sie die Rolle, die die Datenorganisations- und -manipulationsfunktionen von JMP (Datentabellen, Zeilen- und Spaltenmenüs usw.) in der Python-Programmierumgebung erfüllen. Daher ist sie für Python-Datenanalyse-Workflows ziemlich wichtig. Wenn Sie Python direkt in JMP ausführen möchten, ist dieser Blogartikel nicht der richtige für Sie. Schauen Sie sich stattdessen dieses Whitepaper an. Wenn Sie die Datentransformation nicht mehr über die Kommandozeile durchführen möchten, lesen Sie weiter.
DataFrames und Datentabellen
Immer noch da? Super. Okay, im Folgenden werden einige Gemeinsamkeiten von Pandas und deren Pendant in JMP erläutert. Es handelt sich keinesfalls um eine vollständige Liste; sie soll Ihnen lediglich einen ersten Eindruck von den beiden Umgebungen vermitteln.
Als Erstes möchte ich auf den „DataFrame“ eingehen. In Pandas werden hier alle Daten gespeichert. Ähnlich wie Datentabellen in JMP ist er im Wesentlichen eine Sammlung von Datenspalten mit Namen (Spaltenname) usw. Man bearbeitet Spalten und Zeilen (Transformationen, Zusammenfassungen usw.), aber die Bearbeitung erfolgt immer entweder auf dem gesamten DataFrame oder auf einem Teil davon.
In JMP ist die Datentabelle der primäre Datencontainer. Sie können Spalten und Zeilen genauso bearbeiten wie in einem Pandas DataFrame. In beiden Fällen können Sie fehlende Werte in der Datentabelle behandeln. In JMP werden diese entweder durch eine Zelle mit einem Punkt („.“) (für numerische Daten) oder durch eine leere Zelle (für Zeichenkettendaten) gekennzeichnet. Sie können Daten transformieren, zusammenfassen usw. (mehr dazu später). Je mehr Informationen Sie der Software über die Daten geben, desto weniger Aufwand haben Sie – und das bringt mich zu meinem nächsten Punkt.
Spalteneigenschaften und Datentypen
Was Spalteneigenschaften und Datentypen (dtypes in Pandas) angeht, ist JMP klar im Vorteil. Pandas übernimmt einen Großteil seines Datentypverständnisses von einem anderen Python-Paket namens NumPy, was durchaus praktisch ist. NumPy ist zwar recht robust, aber in dieser Hinsicht doch recht eingeschränkt. Es unterstützt etwa acht Datentypen (siehe Tabelle unten [ Quelle ]) mit etwas begrenzter Unterstützung für unterschiedliche Formatierungen (beispielsweise hat es ohne Hilfe Probleme mit Währungen).
| Datenart |
Datentyp |
Skalar |
Array |
Zeichenketten-Aliase |
Dokumentation |
| zeitzonenbewusstes Datum/Uhrzeit |
DatetimeTZDtype |
Zeitstempel |
arrays.DatetimeArray |
'datetime64[ns, ]' |
Zeitzonenverwaltung |
| Kategorisch |
Kategorischer D-Typ |
(keiner) |
Kategorisch |
'Kategorie' |
Kategorische Daten |
| Zeitraum (Zeitspannen) |
PeriodDtype |
Zeitraum |
arrays.PeriodArray |
'Zeitraum[ ]', 'Zeitraum[ ]' |
Zeitbereichsdarstellung |
| spärlich |
SparseDtype |
(keiner) |
arrays.SparseArray |
'Sparse', 'Sparse[int]', 'Sparse[float]' |
Sparse Datenstrukturen |
| Intervalle |
IntervalDtype |
Intervall |
arrays.IntervalArray |
'Intervall', 'Intervall', 'Intervall[ ]', 'Intervall[datetime64[ns, ]]', 'Intervall[timedelta64[ ]]' |
Intervallindex |
| Nullable Ganzzahl |
Int64Dtype , … |
(keiner) |
arrays.IntegerArray |
'Int8', 'Int16', 'Int32', 'Int64', 'UInt8', 'UInt16', 'UInt32', 'UInt64' |
Nullable Integer-Datentyp |
Die Spalteneigenschaften in JMP umfassen etwa 43 Seiten des Buches „Using JMP“ . Sie sind wesentlich umfangreicher und erkennen Datentypen zuverlässig beim Import. Besonders interessant für JMP-Neulinge ist, dass die Spalteneigenschaften weit über die von Pandas verwendeten Datentypen hinausgehen. JMP kann eine Vielzahl von Metadaten verarbeiten, die Aktionen in der gesamten Software auslösen. Zwar lassen sich auch Attribute an einen Pandas DataFrame anhängen, da dieser jedoch lediglich ein Container ist, muss die Unterstützung für Attribute entweder im Code implementiert oder darauf gehofft werden, dass sie im verwendeten Paket enthalten ist. In JMP ist all dies bereits für Sie erledigt.
Tabellieren, Spaltenformeln und Gruppieren
Tatsächlich sind die beiden vorherigen Punkte im Kontext der Frage, die ich beantworten wollte, nicht wirklich relevant. Für unsere Zwecke ist die Datentabelle bzw. der DataFrame lediglich ein Behälter zum Speichern von Daten. Die Spalteneigenschaften bzw. -typen können zwar bei analytischen Betrachtungen hilfreich sein, sind aber für unsere Fragestellung nicht wichtig. Der für uns relevante Teil von Pandas heißt `GroupBy`. Er dient dazu, Daten zu segmentieren und für weitere Analysen vorzubereiten. Ein kurzes Beispiel mit der JMP BigClass-Datentabelle, um die durchschnittliche Größe und das durchschnittliche Gewicht von Jungen und Mädchen nach Alter zu ermitteln, könnte folgendermaßen aussehen:
# Import Pandas
import pandas as pd
# Bring in the data
data = pd.read_csv("/Users/mike.anderson@jmp.com/Desktop/Big Class.csv")
# Put the data into a DataFrame
df = pd.DataFrame(data)
# Run the group by, get the means, and show the results
summ_df= df.groupby(['sex','age']).mean()
print(summ_df)
Die Ausgabe sieht in etwa so aus:
height weight
sex age
F 12 58.600000 100.200000
13 59.000000 95.333333
14 62.600000 96.600000
15 63.000000 102.000000
16 62.500000 113.500000
17 62.000000 116.000000
M 12 57.333333 97.000000
13 61.250000 94.250000
14 65.285714 103.857143
15 65.200000 110.800000
16 68.000000 128.000000
17 69.000000 153.000000
Normalerweise verwenden JMP-Nutzer für diese Datentransformationen primär die Funktionen „Zusammenfassung“ oder „Tabelle“. Sie erstellen möglicherweise sogar Spalten mit dem Formeleditor. Doch die Datentabelle (und die Spaltenliste der Plattform ) birgt ein Geheimnis: Mit dieser Funktion lassen sich nahezu alle Pandas-Operationen und mehr realisieren. Klicken Sie einfach mit der rechten Maustaste auf einen Spaltennamen und wählen Sie „Neue Formelspalte“. Dies funktioniert überall dort , wo eine Spaltenliste vorhanden ist! Anschließend stehen Ihnen zahlreiche Optionen für verschiedene Transformationen zur Verfügung, beispielsweise zum Kombinieren von Spalten oder zum Berechnen von kumulativen Summen in Zeilen. Das ist zwar praktisch, aber noch nichts Besonderes. Richtig interessant wird es erst, wenn Sie in JMP die Option „Gruppieren nach“ für eine Spalte aktivieren. Dadurch werden alle Formelspalten, die Sie erstellen, automatisch anhand der Ebenen einer Gruppierungsvariablen sortiert. Stellen Sie sich das einmal vor: Sie können an beliebiger Stelle in der Software eine Formelspalte erstellen, die nach einer Gruppierungsspalte geschichtet werden kann.
Schauen wir uns ein Beispiel an, was das bedeutet, anhand einer anderen Frage, die ich kürzlich erhalten habe:
Ein Beispiel: ZWEI FRAGEN ZUM PREIS VON EINER!!
Ungefähr zeitgleich mit der ersten Anfrage erreichte mich eine Frage eines anderen Kunden zur numerischen Integration (Fläche unter der Kurve oder AUC) für eine große Stichprobe. Darüber hinaus war er bereit, mir einen zuvor in der Fachzeitschrift „Environmental and Molecular Mutagenesis“ veröffentlichten Beispieldatensatz zur Verfügung zu stellen.
Es stellte sich heraus, dass sich ihr Vorhaben mithilfe von Gruppierungsflags und Funktionsspalten ganz einfach umsetzen ließ. Hier ist die Vorgehensweise (Sie können sie anhand der Daten von der öffentlichen JMP-Website nachvollziehen 
Zunächst visualisieren wir die Daten . Die Details der Studie sind für diese Diskussion nicht relevant, obwohl sie interessant zu lesen ist. Kurz gesagt handelt es sich um eine große Sammlung von Chemikalien mit unterschiedlichen Konzentrationen (Konzentration (µM)) und eine Reihe genetischer Reaktionen. Für unsere Übung berechnen die Forscher die AUC für jede dieser genetischen Reaktionen. Hier sehen Sie die Darstellung im Graph Builder mit einem Spaltenauswahlfeld:
Der erste Schritt zur Berechnung der AUC ist die Einrichtung der Gruppierung. Klicken Sie mit der rechten Maustaste auf die Spalte „Chemikalie“, wählen Sie „Neue Formelspalte“ und anschließend „Gruppieren nach“. Wiederholen Sie diesen Vorgang für die Spalte „Biomarker“. Beachten Sie, dass die Reihenfolge hierbei wichtig ist. Wir gruppieren zuerst nach „Chemikalie“ und dann innerhalb von „Chemikalie“ nach „Biomarker“. Anschließend verwenden Sie einfach die „Neue Formelspalte“ in der Datentabelle, um die Berechnung durchzuführen.

Zur besseren Übersicht habe ich die einzelnen Schritte in separate Spalten aufgeteilt. Und falls es Sie interessiert: Ich verwende hier die Riemann-Summe nach der Trapezregel .
Okay, zurück zur Berechnung. Zuerst benötigen wir den Abstand zwischen den einzelnen Punkten auf der x-Achse (die punktweise Änderung des x-Wertes). Wir wählen die Spalte „Konzentration (µm)“ aus, klicken mit der rechten Maustaste auf die Spaltenüberschrift und wählen „Neue Formelspalte“ > „Zeile“ > „Differenz“. Öffnen Sie nun die Formel in der neuen Spalte, die JMP erstellt hat. Sie sollte in etwa so aussehen:

Beachten Sie, dass JMP die Berechnungen zwischen den Zeilen übernimmt und die Formel so angepasst hat, dass sie zurückgesetzt wird, wenn ein neuer Chemikalien- oder Biomarkertyp erkannt wird.
Als Nächstes benötigen wir den Mittelwert der Werte zwischen jedem Datenpunkt und dem vorherigen. Klicken Sie mit der rechten Maustaste auf die Spaltenüberschrift und wählen Sie „Neue Formelspalte“ > „Zeile“ > „Verzögerung“. Öffnen Sie die Formel und passen Sie sie so an, dass sie die Differenz zwischen den Zeilen berechnet und nicht nur den Wert der vorherigen Zeile ausgibt. Dies ist in diesem Screenshot dargestellt:

Diese beiden Spalten (ich habe sie in der Datentabelle in dx und Du umbenannt) müssen miteinander multipliziert werden, um die Fläche eines Segments zu erhalten. Markieren Sie die beiden Spalten und klicken Sie mit der rechten Maustaste auf den Spaltennamen einer der Spalten. Wählen Sie „Neue Formelspalte“ > „Kombinieren“ > „Produkt“. Die neue Spalte liefert die ungefähre Fläche unter dem Kurvenabschnitt zwischen jedem Datenpunkt und dem jeweils nächsten. Ich habe diese Spalte in der Datentabelle in iAUC (für „momentane AUC“) umbenannt.

Im letzten Schritt werden die Werte für jeden Abschnitt summiert. Dazu klickt man mit der rechten Maustaste auf die Spalte „iAUC“ und wählt „Neue Formelspalte“ > „Zeile“ > „Kumulierte Summe“. Da wir zu Beginn der Übung die Spalten „Gruppieren nach“ ausgewählt haben, wird die Summe für jede Stichprobe im Datensatz zurückgesetzt.

Von hier aus könnten wir mithilfe von „Tabellieren“ oder „Zusammenfassen“ eine Tabelle mit den Maximalwerten für jede Probe erstellen (die ungefähre Gesamtfläche unter der Kurve). Hier ist ein Beispiel für eine gängige Chemikalie:

Schlussbetrachtung
Und das war's schon. Sie können das Verhalten von Pandas ganz einfach mit Strukturen aus JMP nachbilden. Denken Sie einfach daran, die `Group By`-Variable zu verwenden, und schon kann es losgehen. Ganz ohne Hilfsmittel.
Anmerkung der Redaktion:Hast du das gelesen?weitere Folgen unserer Reihe „Ingenieur-Mailbag“Sehen Sie, wie Mike einem Benutzer hilft, der Folgendes verwendet hat:JMPum zu entscheiden, ob man einen Schneeräumdienst in Anspruch nehmen soll und um einzigartige Visualisierungen für STEAM-Bildungsprogramme zu entwickeln.