Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitHintergrund
* Verwendung von Python in der JMP19-Skriptumgebung.
* Erstellung eines Dataframes (df) mit pandas aus einer bestehenden JMP-Datentabelle (dt).
* Eine Funktion, die einen Dataframe als Eingabe benötigt und ein neues Dataframe-Ergebnis zurückgibt. Nennen wir sie df_results.
* Die Ergebnisse werden zurück in die JMP-Datentabellenspalte übertragen.
Das funktioniert zwar, aber zwei Dinge lassen mich vermuten, dass ich etwas falsch mache. Erstens erhalte ich eine Warnung in der lokalen Protokollausgabe. Zweitens dauert der erste Durchlauf mit einer sehr großen Anzahl von Zeilen sehr lange. Mein Code-Timer zeigte 25 Sekunden für 100.000 Zeilen an. Beim zweiten Durchlauf dauert es nur noch 3 Sekunden. Ich habe den Timer so konfiguriert, dass er mir Details zu jedem Schritt liefert, damit ich herausfinden kann, ob eine bestimmte Codezeile den größten Teil der Zeit in Anspruch nimmt.
Dies ist die eine Codezeile, die ich hinterfrage. Sie benötigte 25 Sekunden für 100.000 Zeilen – und zwar nur beim ersten Durchlauf, nachdem die Spalte mit dem anfänglich konstanten (oder leeren – beides wurde getestet) Wert befüllt war. Danach ging es bei jedem weiteren Durchlauf fast zehnmal schneller.
dt[ColumnName] = df_results[ColumnName]
Dies ist die Warnmeldung im eingebetteten Protokoll.
FutureWarning: Die Verwendung von Series.__getitem__ zur Behandlung von Schlüsseln als Positionen ist veraltet. In einer zukünftigen Version werden ganzzahlige Schlüssel immer als Labels behandelt (entsprechend dem Verhalten von DataFrames). Um auf einen Wert anhand seiner Position zuzugreifen, verwenden Sie `ser.iloc[pos]`.
Ich habe dies auch für insgesamt vier verschiedene Spalten aus zwei verschiedenen Dataframes durchgeführt. Alle zeigten dasselbe Verhalten (und dieselbe Warnung): Langsamer erster Durchlauf, danach schnelle Wiederholungen. Der Unterschied zwischen Spalte 1, 2, 3 und 4 war vernachlässigbar.
Dies ist nur ein Ausschnitt aus einer großen Tabelle mit 1,3 Millionen Zeilen. Wenn ich also nicht gleich beim ersten Versuch die höheren Geschwindigkeiten erreiche, werden aus 25 Sekunden x 4 Spalten über 250 Sekunden x 4 Spalten.
Danke
Automatisierung und SkripterstellungBetreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitIn JMP 18 musste eine Datentabelle Spalte für Spalte aus einem Dataframe aufgebaut werden. JMP 19 unterstützt das Portable Data Frame Protocol (PDFP), sodass für die Konvertierung von dt nach df jeweils nur eine Zeile Code benötigt wird, und für die Konvertierung von df nach dt im Speicher ebenfalls nur eine Zeile.
Beachten Sie außerdem, dass Python beim ersten Ausführen eines Python-Skripts in JMP initialisiert werden muss. Beim ersten Import eines Pakets muss dieses geladen werden, gegebenenfalls einschließlich gemeinsam genutzter Bibliotheken oder der Bytecode-Kompilierung der .py-Dateien.
Die Warnung stammt vom Pandas-Paket. Um sie zu beheben, verwenden Sie den empfohlenen Befehl `ser.iloc[pos]`. Die JMP-Datentabelle `dt` kann entweder über einen nullbasierten Spaltenindex oder über den Spaltennamen indiziert werden. Die Indizierung ist schneller, da sie Stringvergleiche vermeidet.
Hilfe -> Skriptindex, Kategorie 'Python', jmp.from_dataframe. Beispiel 'JMP zu Pandas'.
import jmp
import jmputils
try:
if not jmputils.is_installed('pandas'):
jmputils.jpip('install', 'pandas', echo=False)
except Exception as e:
print(f'Install failed with exception: {e}')
import pandas as pd
dt = jmp.open(jmp.SAMPLE_DATA + "Big Class.jmp")
pandas_df = (pd.api.interchange.from_dataframe(dt))
print(pandas_df)
...
# new dt_result data table from dataframe df_result
dt_result = jmp.from_dataframe( df_result )
# or continue to do the loop on columns if you need to update the original data table from the resulting dataframe.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitUnd wie kann man am schnellsten eine einzelne JMP-Spalte mit neuen Werten aus Python füllen?
z. B. für eine Datentabelle mit 100.000 Zeilen?
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitDanke Paul, ich werde jmp.from_dataframe implementieren, um wieder zu datatables zu gelangen und den Fehler zu vermeiden.
Der andere Teil meiner Frage bezog sich auf den enormen Geschwindigkeitsunterschied. Um das zu beantworten, musste ich sicherstellen, dass ich die langsame Berechnung zuverlässig reproduzieren konnte. Zuerst gelang mir das nicht. Alle Durchläufe, selbst der erste nach dem Öffnen von JMP und dem Laden von Python, waren sehr schnell. Dann wurde mir klar, dass es möglicherweise einen entscheidenden Unterschied gibt. Wenn ich eine neue Spalte hinzufüge (manuell, ich hatte sie noch nicht im Code hinterlegt) und den Code ausführe, ist die Aktualisierung dieser neuen Spalte nur beim ersten Mal langsam.
Zum Testen habe ich vier Spalten aktualisiert, drei davon waren bereits vorhanden, die vierte wurde neu erstellt. Die Aktualisierung von 100.000 Zeilen in Spalte 1 dauerte eine Sekunde, die Aktualisierung von Spalte 2 eine weitere Sekunde, die Aktualisierung von Spalte 3 noch eine und die Aktualisierung von Spalte 4 schließlich 19 Sekunden.
Ich habe eine weitere Tabelle und eine zusätzliche vierte Spalte erstellt. Wenn ich die Datentabelle mit der neuen Spalte speichere und schließe, sie dann wieder öffne und anschließend den Code ausführe, wird die neue vierte Spalte in etwa einer Sekunde aktualisiert – genauso schnell wie die Spalten 1, 2 und 3. Entscheidend ist jedoch: Wenn ich die Datentabelle mit der neuen vierten Spalte nur speichere, sie aber nicht schließe und wieder öffne, bevor ich den Code ausführe, dauert die Aktualisierung der vierten Spalte weiterhin etwa 19 Sekunden.
Das sagt mir, dass die Geschwindigkeit mit einer Eigenart der Speicherverwaltung von JMP zusammenhängt.
Ich weiß nicht, ob dieses Problem gelöst werden kann/muss, und vielleicht tritt es auch nur auf, wenn ich den Schritt „from_dataframe“ nicht verwende. Es ist einfach ein sehr merkwürdiges Verhalten, und ich bin froh, dass ich es reproduzieren konnte. Jetzt kann ich die verbesserte Codeversion testen und sehen, ob das Problem weiterhin besteht.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitEiner meiner Kollegen wies mich darauf hin, dass es in JSL die Funktionen Start Data Update und End Data Update gibt, also....
jmp.run_jsl( 'dt << Begin Data Update;' )
# your python code filling new column
...
jmp.run_jsl( 'dt << End Data Update;' )
Höchstwahrscheinlich werden wir dies mit Python unterstützen wollen. Vermutlich mithilfe eines with-Blocks, um die Aktualisierung der Benutzeroberfläche der Tabelle beim Füllen/Aktualisieren einer großen Anzahl von Zeilen zu unterbrechen.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitEs würde die gesamte Spalte mithilfe von dt[index], umschlossen mit jsl Begin Data Update, festlegen.
jmp.run_jsl( 'dt << Begin Data Update;' )
dt[ index ] = list_like_object # numpy array, list, dataframe column,...
jmp.run_jsl( 'dt << End Data Update;' )
Oder indem Sie die Datentabelle zunächst unsichtbar erstellen, bis Sie sie gefüllt haben, und sie dann sichtbar machen.
import jmp
dt = jmp.DataTable('Powered By Python', 40, visibility='Invisible')
...
# fill table
...
jmp.globals['jdt'] = dt # set jdt in JSL to reference dt
jmp.run_jsl('::jdt << Show Window(1);')
Der optionale Sichtbarkeitsparameter kann ab JMP 19 verwendet werden. jmp.globals[ ] ist eine Funktion von JMP 19.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitDer Befehl `jmp.run_jsl( 'dt << Begin Data Update;' )` geht davon aus, dass `dt` die JSL-Variable für die Tabelle sowohl in JSL als auch in Python ist. Dies kann beispielsweise durch ein `Send(dt);` in Python verursacht werden, ist aber nicht unbedingt der Fall, wenn die Tabelle in Python erstellt wurde.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitVielen Dank für die Erklärung.
Also, der Code:
dt[ index ] = list_like_object
Füllt Python die Spalte schrittweise ? Wodurch wird das Geschwindigkeitsproblem verursacht?
Es sieht ähnlich aus wie
dt[ 0, columnname] = [values ...]
in JSL , wodurch die Spalte in einem Schritt gefüllt wird – und nicht von dt << Begin/end Data Update umschlossen werden muss.
Gut zu wissen. Wo finde ich weitere Informationen dazu?
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitIch weiß nicht, wie vielen Nutzern bewusst ist, wie wichtig das ist.
dt << Begin Data Update;
Es geht darum, guten Code zu schreiben. Aber ich bin mir sicher, dass viele Benutzer das nicht wissen.
Verwandter Wunsch von @bswedlove für for each row():
für jede Zeile (Datenaktualisierung=1, ...)
Eine hervorragende Idee , eine Lösung zu institutionalisieren – damit das Problem für den Benutzer verschwindet (die Lösung ist immer verfügbar).
Gilt für JSL und Python.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die Berechnungsgeschwindigkeit„ Die JMP-Datentabelle dt kann entweder über einen nullbasierten Spaltenindex oder über den Spaltennamen indiziert werden. Ein Index ist schneller, da er Zeichenkettenvergleiche vermeidet. “
Ich versuche, den Code mithilfe von Indizes umzuschreiben, kann aber die entsprechende Syntax für die Bestimmung des Spaltenindex einer Datentabelle anhand des Namens, den ich für Dataframes habe, nicht finden.
dfColumnIndex = df.get_loc['NameofDataFrameColumn']
dtColumnIndex = ???
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die Berechnungsgeschwindigkeit@jthi , wie nennt man die Bezeichnung für „einen Code hinzufügen, um ein Problem zu beheben, das gar nicht existiert“?
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitWenn ein DataFrame (df) aus einem DataFrame (dt) erstellt wurde, geht man davon aus, dass beide denselben Index haben. Falls Sie dem DataFrame Spalten hinzugefügt haben oder der eine nicht der Ursprung des anderen ist, bleibt Ihnen wahrscheinlich nur die Verwendung von `dt['col_name'] =`. Dies ist zwar im Vergleich zu einem Index nicht allzu aufwendig, vergleicht aber Zeichenketten und nicht direkt numerisch.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitDas alles geschieht mithilfe der Protocol Buffers von Python, wo die Daten im Speicher zwischen den unterstützten Speicherblöcken abgebildet werden. Die Verwendung von `Begin | End Data Update` ist möglicherweise nicht erforderlich, aber wenn nicht die gesamte Spalte auf einmal abgebildet werden kann, wird auf die Iteration über die Werte zurückgegriffen. Daher bietet die Verwendung von `Data Update`-Anweisungen eine gute Sicherheitsmaßnahme.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitIch habe zahlreiche Experimente und verschiedene Methoden durchgeführt. Einige führten zu Warnungen, andere nicht. Am einfachsten schien es zu sein, ein dt aus dem df zu erstellen und dieses dann zum Datentransfer zu verwenden. Dabei traten nie Fehler auf.
Was das Geschwindigkeitsproblem angeht … der EINZIGE Unterschied bestand darin, ob ich Werte in eine neu erstellte Spalte oder in eine bereits vorhandene Spalte beim Öffnen (oder Erstellen) der Datentabelle schreiben wollte. Neu erstellte Spalten wurden extrem langsam aktualisiert. Bereits vorhandene Spalten hingegen wurden sehr schnell aktualisiert.
Ergebnisse der letzten Textanalyse (100.000 Zeilen). Vor der Ausführung dieses Codes waren bereits 4 Parameter vorhanden, und 5 neue Spalten wurden hinzugefügt. Insgesamt wurden 9 Spalten aktualisiert.
Diese Datentransfers verwendeten alle die Syntax `dt['colname'] = dt_results['colname']`. Es wurden keine weiteren DataFrames verwendet, nachdem `dt_results` mithilfe von `DF` erstellt wurde.
Erstellungszeit des Schritts df_results: 0,3434 Sekunden
Schritt Parameter 1 Übertragungszeit: 0,1795 Sekunden
Schritt Parameter 2 Übertragungszeit: 0,1758 Sekunden
Schritt df_results Erstellungszeit: 0,0231 Sekunden #Dies ist ein neuer Satz von Ergebnissen, die von verschiedenen df-Funktionen zurückgegeben werden.
Schritt Parameter 3 Übertragungszeit: 0,1838 Sekunden
Schrittparameter 4 Übertragungszeit: 0,1890 Sekunden
Der Code lautete hier: dt['NewCol1Test'] = df_results[stringnameofcolumn]
FutureWarning: Die Verwendung von Series.__getitem__ zur Behandlung von Schlüsseln als Positionen ist veraltet. In einer zukünftigen Version werden ganzzahlige Schlüssel immer als Labels behandelt (entsprechend dem Verhalten von DataFrames). Um auf einen Wert anhand seiner Position zuzugreifen, verwenden Sie `ser.iloc[pos]`.
df zu dt mit Namen – Übertragungszeit: 15,8251 Sekunden
Der Code hier lautete: dt['NewCol2Test'] = df_results.iloc[:,dfColumnIndex]
FutureWarning: Die Verwendung von Series.__getitem__ zur Behandlung von Schlüsseln als Positionen ist veraltet. In einer zukünftigen Version werden ganzzahlige Schlüssel immer als Labels behandelt (entsprechend dem Verhalten von DataFrames). Um auf einen Wert anhand seiner Position zuzugreifen, verwenden Sie `ser.iloc[pos]`.
Ich weiß nicht, warum diese Warnung trotz der Verwendung von iloc weiterhin ausgegeben wurde.
df zu dt mit iloc-Übertragungszeit: 16,0874 Sekunden
Der Code lautete hier: dt['NewCol3Test'] = dt_results[dfColumnIndex]
Übertragungszeit von dt-Index zu dt-Name: 14,5659 Sekunden
Der Code lautete hier: dt[NewColumnIndex] = dt_results[dfColumnIndex]
dt-Index-zu-dt-Index-Übertragungszeit: 14,4699 Sekunden
Der Code lautete hier:
jmp.run_jsl('dt << Begin Data Update;')
dt['NewCol5Test'] = dt_results[dfColumnIndex]
jmp.run_jsl('dt << End Data Update;')
#Warnung/Fehlerergebnis:
"Name nicht aufgelöst: dt beim Zugriff oder der Auswertung von 'dt' , dt/*###*/
in Zeile 1
Name nicht aufgelöst: dt beim Zugriff oder der Auswertung von 'dt' , dt/*###*/
in Zeile 1“
#Dieser Ausdruck befand sich tatsächlich in derselben Zeile wie die zweite Fehlermeldung 'in Zeile 1'.
dt zu dt w Indizes in Anfangs-/Endaktualisierungs-Übertragungszeit: 14,3627 Sekunden
#Abschließende Zusammenfassung der Laufzeit bei 100.000 Zeilen.
Gesamtausführungszeit: 77,0904 Sekunden
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitSpeichern Sie Ihre Daten (*), bevor Sie diesen Code ein zweites Mal ausführen (**) - oder aktivieren Sie die Datenaktualisierung am Anfang/Ende!
import jmp
import numpy as np
dt = jmp.open(jmp.SAMPLE_DATA + "Wafer Stacked.jmp")
jmp.globals['jdt'] = dt
jmp.run_jsl('Graph Builder( Variables( Y( :defects ) ), Elements( Bar( Y, Label( "Label by Value" ) ) ))');
# jmp.run_jsl('jdt << Begin Data Update;')
dt[ 5 ] = [np.random.randint(1000)]*177875
# jmp.run_jsl('jdt << End Data Update;')
(*) Nur ein Scherz, Ihre Daten gehen nicht verloren – machen Sie sich einfach einen Kaffee und warten Sie, bis JMP fertig ist.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die Berechnungsgeschwindigkeit
@hogi schrieb:
... ein zweites Mal (**)
(**) TS - 00251136
@Dahlia_Watkins bemerkte, dass manchmal zwei Ausführungen des Codes nötig sind, um das Geschwindigkeitsproblem zu beheben.
Scheint ein Timing-Problem zu sein.
Möglicherweise wird beim ersten Ausführen des Codes das Diagramm erst erstellt, nachdem Python die zeilenweise Datenaktualisierung abgeschlossen hat.
bearbeiten:
Tatsächlich ist das Diagramm als interaktives Element nicht notwendig, um die Aktualisierung der Python-Daten zu verlangsamen.
Weitere Beispiele ohne interaktive Elemente finden Sie in den folgenden Beiträgen.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitIch habe das Thema zu „Vorsicht: Stellen, an denen Jmp unerwartetes Verhalten zeigt“ hinzugefügt.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitZum ursprünglichen Problem: „Langsamer Datenzugriff, wenn eine neue Spalte hinzugefügt wird“
Hier ein anschauliches Beispiel:
import jmp
dt = jmp.DataTable('dt_new', 50000)
col = dt.new_column("newCol")
# --------- cut here to make it slow - why? -------------
dt[ 0 ] = [1]*50000
In zwei Schritten aufgeteilt, benötigt JMP einige Sekunden, um die 50.000 Einträge zu aktualisieren.
rätselhaft:
Wenn beide Blöcke in einem Durchlauf ausgeführt werden, gibt es mit JMP keine Probleme.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitNeben den in @Paul_Nelsons Beitrag erwähnten Umgehungslösungen dachte ich, es gäbe noch einige weitere, wie zum Beispiel:
- Verwenden Sie JSL, um die Spalte / die Datentabelle zu erstellen.
- Verwenden Sie JSL, um die Spalte mit Dummy-Werten zu füllen.
- Verwenden Sie JSL, um die Datentabelle zu speichern, schließen Sie sie und öffnen Sie sie erneut.
Viele davon sehen auf den ersten Blick gut aus – aber das ist irreführend.
Die hohe Geschwindigkeit ergibt sich lediglich daraus, dass dieselben Werte erneut in die Spalte geschrieben werden und JMP keine "Datenaktualisierungswarnung" auslöst:
z.B
jmp.globals['jdt'] = dt
jmp.run_jsl('''
nc = n cols(jdt);
Column(jdt,nc) << set each value(1)
''');
nc = dt.ncols
data = [1]*50000
dt[ nc - 1 ] =data
Dasselbe Wunder mit Python:
# 1st: slow
nc = dt.ncols
dt[ nc - 1 ] = range(50000)
# fast ! (same values!)
dt[ nc - 1 ] = range(50000)
# new values: slow again
dt[ nc - 1 ] = [5]*50000
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitMan kann einen Auslöser einrichten, um eine Benachrichtigung zu erhalten, wenn JMP der Meinung ist, dass Daten aktualisiert wurden.
import jmp
dt = jmp.open(jmp.SAMPLE_DATA + "Big Class.jmp")
jmp.run_jsl('''
New Column( "trigger",
Formula(
If( Row() == 1,
Try( Caption( Char( ::i=::i+1 ) ), ::i = 1 )
);
:age;i
)
)
''')
dt[ 1 ] = range(40)
dt[ 1 ] = range(40) # no data update !
dt[ 1 ] = [2]*40
# for loop without begin/end data update -> finished before JMP notices the data update
jmp.run_jsl('''
for each row(:age = row());
wait(5);
''')
# for loop without begin/end data update - and some delay to give JMP the time to notice:
jmp.run_jsl('''
for each row(:age = 2*row();wait(0))
''')
Es findet also tatsächlich keine "Datenaktualisierung" statt, wenn die ursprünglichen und die neuen Werte identisch sind.
Implementiert, um Endlosschleifen zu bekämpfen? Großartig!
Interessant,
import jmp
dt = jmp.open(jmp.SAMPLE_DATA + "Wafer Stacked.jmp")
jmp.run_jsl('''
delete symbols(::i)
New Column( "trigger",
Formula(
If( Row() == 1,
Try( Caption( Char( ::i=::i+1 ) ), ::i = 1 )
);
:Y_Die;i
)
)
''')
nr = dt.nrows
dt[ 4 ] = range(nr)
Dauert länger als 1 Minute - Und ich zähle bis 2.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die Berechnungsgeschwindigkeit
@Paul_Nelson wrote:
...
Most likely we will want to do support this from Python. Probably using a with block to suspend the UI updates of the table when filling / updating large number of rows.
Tolle Idee!
Bitte achten Sie darauf, die Interaktivität auch dann wieder zu aktivieren, wenn Python innerhalb des "with"-Blocks einen Fehler ausgibt.
Alternativ dazu:
Bitte fügen Sie dem Datengitter einen Indikator hinzu, der anzeigt, wann die Interaktivität deaktiviert ist, weil ein Fehler aufgetreten ist.
Datenaktualisierung beginnen, ohne Datenaktualisierung abzuschließen .
Indikator: Interaktivität für diese Datentabelle deaktiviert
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitErgebnisse der vorherigen Beiträge – zusammengefasst:
import jmp
# open data table and wait for the "Interactivity Manager" to get active
jmp.run_jsl('''
dt = new table("test", add rows(100000), new column ("col"));
Python send(dt);
wait(0) // disable the delay to make it fast
'''
);
nr=dt.nrows
# Python data update: slow!
dt[ 0 ] = range(nr)
# --- run step by step: -----
# same values: fast
dt[ 0 ] = range(nr)
#new values: slow
dt[ 0 ] = [1]*nr
Das Aktualisieren einer JSL-Spalte über Python ist sehr langsam.
Ausnahmen:
- Schreibzugriff direkt nach dem Erstellen/Öffnen der Datentabelle (bevor ein "Interaktivitätsmanager" aktiv ist).
- Es erfolgt keinerlei Aktualisierung (die Werte ändern sich nicht).
und die in @Paul_Nelsons Beitrag erwähnten Umgehungslösungen:
- private Datentabellen
- Python-Datenaktualisierung, eingeschlossen in JSL Begin/End Data Update()

Schneller Datenzugriff mit Python – nur mit JSL-Unterstützung ; )
Ich nehme an, die Probleme sind so bedeutend, dass sie in der nächsten ".x"-Version behoben werden...
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitIm zweiten Fall muss es sich tatsächlich um eine private Tabelle handeln (Sichtbarkeit='Privat'). Die Tabelle 'Unsichtbar' verfügt zwar über eine Benutzeroberfläche, obwohl sie ausgeblendet ist, und ist daher aufgrund der Aktualisierungen der Benutzeroberfläche in der Datentabelle bei jeder Zellenbearbeitung weiterhin träge.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitJa, das ist ein wichtiger Punkt. Wir arbeiten bereits an einer Lösung. Wir möchten, dass die Performance von Python so gut ist, dass Benutzer Python nutzen möchten und keine inoffiziellen Methoden verwenden müssen, um eine bessere Performance zu erzielen.
Es wundert mich, dass dies weder in JMP 18 noch während der EA-Tests von JMP 19 aufgefallen ist. Das `jmp.DataTable`-Objekt ist im Kern die JSL-Datentabelle. Das Python-Objekt ist lediglich eine Referenz auf die zugrundeliegende JMP-Datentabelle, und wir rufen deren interne Methoden auf. Daher ist `run_jsl('dt << Begin Data Update')` relevant. Der Zweck von `jmp.run_jsl(''' code '''')` bestand darin, JSL-Aufrufe aus Python für noch nicht implementierte Funktionen zu ermöglichen oder, wie in diesem Fall, einen Fehler in der Spaltenaktualisierungsleistung zu beheben.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitSchön zu hören, dass das Problem behoben wurde.
Warum wurde es vorher nicht entdeckt?
Ich vermute, viele Nutzer verwenden Python für den Datenimport und die Datenaufbereitung, bevor sie die Daten in JMP übertragen – wo sie die Daten dann nicht mehr direkt mit Python bearbeiten. Wenn sie die Python-Funktionen `get(dt)` (JSL) oder `from_dataframe()` (Python) verwenden, tritt dieses Problem nicht auf.
Hinweis: Spaltenweise Übertragung wie in „Erste Schritte mit der Python-Integration in JMP 18“.
Hierbei kommt es auf die Größe der Datentabelle an. Ist die Tabelle klein genug, werden die neuen Spalten hinzugefügt, bevor der „Interaktivitätsmanager“ aktiviert wird.
Als wir das Problem auf unserer Seite entdeckten, hatten wir Zugriff auf JMP19EA und freuten uns, festzustellen, dass wir die Tabellengenerierung mit from_dataframe() beschleunigen konnten – mit dem zusätzlichen Vorteil eines deutlich einfacheren Codes.
Andererseits tritt das Problem auf, wenn Python verwendet wird, um einzelne Spalten einer bestehenden JMP-Datentabelle zu aktualisieren , wie beispielsweise in JMPyFacade: Bridging JMP and Python for Seamless Engaging Analysis . Als JSL-Experte hat @jthi die notwendige Datenzusammenführung für private Tabellen ohne großes Nachdenken implementiert.
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitInformationen, die im heutigen Scripters Club geteilt wurden:
das Geschwindigkeitsproblem mit
dt[ index ] = list_like_object
wird in JMP 19.0.3 behoben : )
Betreff: Python in JMP: Best Practices für die Umwandlung von DataFrame-Spalten in DataTable-Spalten und Auswirkungen auf die BerechnungsgeschwindigkeitJetzt erhältlich:
