Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Eine aktuelle Community-Diskussion Skript zum Suchen und Ersetzen eines numerischen Werts durch einen fehlenden Wert in der gesamten Tabelle hatte einen sehr schönen Eintrag zur Verfügung gestellt von @SDF1 Das wurde als Lösung ausgewählt
names default to here(1);
dt=current data table();
For( i = 1, i <= N Rows( dt ), i++,
For( l = 1, l <= N Cols( dt ), l++,
If( Column( l )[i] == 999,
Column( l )[i] = .
)
)
);
Als ich mir die Lösung ansah, kam mir eine alte Lehre in den Sinn, die ungefähr lautete: „Durchlaufen Sie keine Datentabellen.“Das Schleifen ist langsam. Nutzen Sie die integrierten JMP-Funktionen.“
Also fing ich an zu modifizieren @SDF1 Code.
Ich habe festgestellt, dass mein Fallback-Standard „Get Rows Where()“ schneller sein würde.Schließlich können damit alle gefundenen Zeilen mit einer Zuweisungsanweisung gesetzt werden, nachdem der „sehr schnelle“ Get Rows Where() die Zeilen gefunden hat.
Eine andere Lösung, die ich gesehen habe geschoben Von der Community empfohlen ist die Recode-Funktion in JMP.
Also:
Hypothese: Die integrierten JMP-Funktionen „Get Rows Where“ und „Recode“ sind schneller als das Schleifen nach unten und über eine gesamte Datentabelle.
Ich habe die Datentabelle „Halbleiterfähigkeit“ als Tabelle mit guter Größe, 132 Spalten und 1455 Zeilen, ausgewählt
Ich habe ein kleines Skript geschrieben, das 10 Zufallswerte in jeder Spalte auf 999 setzt.
names default to here(1);
dt=current data table();
for(i=5,i<=ncols(dt),i++,
if(col stddev(ascolumn(dt,i))!=0,
for(k=1,k<=10,k++,
column(dt,i)[randominteger(1,1455)]=999;
)
));
Names Default To Here( 1 );
dt = Current Data Table();
start = HP Time();
For( i = 5, i <= N Cols( dt ), i++,
dt << Recode Column(
As Column( dt, i ),
{If( _rcNow == 999, ., _rcNow )},
Target Column( As Column( dt, i ) )
)
);
show(hptime()-start)
Dies ist der ursprüngliche Wert, der in der oben erwähnten Diskussion geändert werden soll.Die 999 soll durch die Skripte in „missing“ (.) geändert werden.
Methode:
- Starten Sie JMP 16.
- Lesen Sie die Datentabelle zur Halbleiterfähigkeit ein
- Führen Sie das Skript aus, um die 999 Werte in jeder Spalte festzulegen
- Wiederholen Sie die beiden oben genannten Schritte für jede der drei Methoden und kodieren Sie die Zeit auf die Millisekunde genau neu.
- Wiederholen Sie die obigen Schritte für JMP15
Hier ist das Skript für den Recode
Names Default To Here( 1 );
dt = Current Data Table();
start = HP Time();
For( i = 5, i <= N Cols( dt ), i++,
dt << Recode Column(
As Column( dt, i ),
{If( _rcNow == 999, ., _rcNow )},
Target Column( As Column( dt, i ) )
)
);
show(hptime()-start)
Der Code für Get Rows Where
names default to here(1);
dt=current data table();
start=hptime();
for(i=5,i<= ncols(dt),i++,
column(dt,i)[dt<<GET rows="" where=""></GET>
Und hier sind die überraschenden Ergebnisse

Die For-Schleife gewinnt zweifellos.Und den Ergebnissen zufolge sollte Get Rows Where sparsam verwendet werden.
Kommentare und Korrekturen sind willkommen......
Datenmischung und -bereinigungQualitäts- und VerfahrenstechnikBetreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?
@jthi schrieb:
Ich habe mich vielleicht etwas zu sehr damit beschäftigt (habe aber zumindest eine Vorstellung davon, wie ich diese Art von Tests später durchführen kann, wenn es sein muss).
Ich habe eine Art Testskript mit verschiedenen Ausdrücken geschrieben, um verschiedene Möglichkeiten zum Ersetzen der 999 durch fehlt zu testen.
....
Ich habe es gerade verwendet @jthi Skript:
https://community.jmp.com/t5/Discussions/Should-you-Loop-through-a-data-table-or-use-Recode-or-use-Get/mp/381766/highlight/true#M63232
um die Leistung der verschiedenen Ansätze auf einem System mit Jmp (16.2 & ) 17.1 zu reproduzieren.
Ich habe einige Ansätze hervorgehoben (inkl. loc ), die heutzutage drinnen sein müssen Beginn/Ende der Datenaktualisierung *)
um eine starke Zeitverlängerung mit zunehmendem prozentualen Anteil von 999 Sekunden zu vermeiden.
Unterschiede um den Faktor 2 können durch die unterschiedlichen Rechner verursacht werden.
Wer hat ein System mit Jmp 15 und 17 – zum direkten Vergleich?
*) obwohl die Teilmenge „unsichtbar“ geöffnet wurde.

Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?@hogi schrieb:
...
Wenn einem Benutzer das Problem bekannt ist, ein sehr billig Die Lösung besteht darin, eine hinzuzufügen Eval()
billig hinsichtlich der Komplexität des JSL-Codes im Vergleich zur Zeitstrafe.
Aber für längere Tische Eval(i) verliert deutlich gegen Substitute(... ,NameExpr(As Column()))) .
Also: immer noch recht schnell (im Vergleich zur Originalversion
, aber nicht so schnell, wie ich es erwartet hätte.
Warum? Was ist der grundlegende Unterschied?
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Hm, vielleicht ist es möglich, JSL in einen benutzerfreundlichen Modus zu schalten (der Variablen vorab auswertet, wenn dies zu einer besseren Leistung führt)?
Wunsch: Holen Sie sich Zeilen mit: Geschwindigkeitsproblem
Wenn ein Benutzer sich des Problems bewusst ist, wird ein sehr billig Die Lösung besteht darin, eine hinzuzufügen Eval():
start = HP Time();<BR />for(i=5,i<= ncols(dt),i++,<BR />dt << get rows where( As Column( dt, Eval(i) ) == 999 );<BR />);<BR />Show( (HP Time() - start) / 1000000 );start = HP Time();
i = 5;
dt << get rows where( As Column( dt, Eval(i) ) == 999 );
Show( (HP Time() - start) / 1000000 );
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Hi @ron_horne , das Problem liegt bei der Holen Sie sich Zeilen wo , daher sollte die Geschwindigkeit unabhängig von solchen Einstellungen sein/ist.
Andererseits macht es einen großen Unterschied, ob der Spaltenindex explizit ist oder ob es sich um eine Variable handelt (auch wenn der Variablen ein Wert zugewiesen ist).
Das war mir nicht klar – wie gut, dass ich dieses Gespräch fand!
Ich weiß nicht, wie viele JSL-Codes es gibt, die um den Faktor ~ N (Zeilen der Datentabelle) schneller sein könnten ...
Kann das Problem durch die Vorgänge im Hintergrund von JSL behoben werden?
Oder gibt es in der JSL-Architektur etwas Grundlegendes, das besagt, dass ein solches Verhalten beabsichtigt ist und nicht geändert werden kann?
Wenn ja: Eine Warnmeldung könnte Programmierern helfen, nicht in die Falle dieses Problems zu geraten ...
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Semiconductor Capability.jmp" );
For( k = 1, k <= 4, k++,
dt << Concatenate( dt, dt, dt, Append to first table )
);
nuke = Function( {},
For( k = 1, k <= 10, k++,
Column( dt, 5 )[Random Integer( 1, 1455 )] = 999
)
);
//dt << show window(0);
//dt<< Begin Data Update();
nuke();
start = HP Time();
i = 5;
dt << get rows where( As Column( dt, i ) == 999 );
Show( (HP Time() - start) / 1000000 );
nuke();
start = HP Time();
dt << get rows where( As Column( dt, 5 ) == 999 );
Show( (HP Time() - start) / 1000000 );
//dt << End Data Update();
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Danke @txnelson
Könnten Sie bitte die Auswirkung der Verwendung unsichtbarer und privater Tabellen auf die verschiedenen Methoden abschätzen? Sie müssen der schnellste Weg sein, ein Skript zu ändern, um die Leistung zu steigern.
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Wow, was für ein wunderbarer Trick 
Ich befürchtete, dass es Probleme geben würde Fehlender Wertcode startet, sobald Sie es versuchen:
Col Maximum(:NPN3)
[Wie wir das wissen ausgeschlossen Reihen müssen sein ausgeschlossen in Col Aggregation von Hand (oder besser: per Gruppiere nach Streit).]
Aber die Überraschung: Col Aggregationen Respekt Fehlende Wertcodes 

Um wählerisch zu sein: die OP-Frage des ursprünglichen Beitrags war ziemlich implizit:
Und aus den Ergebnissen geht hervor, dass Zeilen wo abrufen sollte sparsam verwendet werden.
Kommentare und Korrekturen sind willkommen......
übersetzt – mit einem ungutem Gefühl im Bauch – als: „Warum zum Teufel?!?“
Dank an @ErraticAttack für die Lösung des Rätsels 
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Es war eine so unterhaltsame und informative Diskussion, der man folgen konnte! Brillante Antworten. Ich bin wirklich nicht qualifiziert, hier etwas Wertvolles hinzuzufügen, also werde ich auf „Schummeln“ zurückgreifen.
Bei der OP-Frage ging es darum, Werte von 999 in den Daten durch fehlende zu ersetzen, da es sich bei den 999 um fehlende Wertcodes handelt und wir diese nicht in die Berechnungen einbeziehen möchten. Das ist überhaupt nicht im Sinne dieser sehr interessanten Fragestellung, aber mein Beitrag ist, dass die Ausnutzung der Codespalteneigenschaft für fehlende Werte schneller ist als das Ersetzen der Daten und für *die meisten* Zwecke das Gleiche erreicht 
start = HP Time();
For( i = 5, i <= N Cols( dt ), i++,
Column(dt,i) << Set Property( "Missing Value Codes", {999} )
);
Show( HP Time() - start);
~ 0,007 Sekunden auf meinem M1-Mac.
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Ach, ich wusste es nicht:
:Name() verhält sich wie Als Spalte() ?
Nicht so klar aus dem Scripting-Index 
Also, mit Ersatz Und Als Spalte() anstatt Eval(Parse(Eval Insert(JSL Quote(name("^names[i]^") es ist:
start=hptime();
for(i=5,i<= ncols(dt),i++,
Eval(Substitute(Expr(column(dt,i)[dt<<GET rows="" where=""></GET>
Und danach dieser überraschende Befund Ich bin hier fast überrascht, dass das Holen Sie sich Zeilen wo geht auch schnell, wenn der Zahlenvergleich durch einen Zeichenvergleich ersetzt wird 
start=hptime();
for(i=5,i<= ncols(dt),i++,
Eval(Substitute(Expr(column(dt,i)[dt<<GET rows="" where=""></GET>
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Ja ich verstehe @brady_brady . Man könnte jedoch Folgendes tun:
NamesDefaultToHere(1);
// Make an example table with some rogue '999' values
nr = 10; // Number of rows
nc = 10; // Number of columns
p = 0.1; // Fraction of rogue values
val = 999; // Rogue value
m = J(nr, nc, RandomInteger(1, 10));
m = Shape(m, nr*nc, 1);
m[RandomIndex(nr*nc, Floor(nr*nc*p))] = val;
m = Shape(m, nr, nc);
dt = AsTable(m);
dt << setName("Rogue Values");
Wait(3);
// Set rogue values to '.'
mask = J(nr*nc, 1, 1);
mask[Loc(dt[0,0] == val)] = .;
mask = Shape(mask, nr, nc);
dt[0,0] = mask :*</img> dt[0,0];
Aber ich bezweifle stark, dass dies schneller gehen würde als das, was Sie bereits haben, nicht zuletzt wegen der elementweisen Multiplikation.
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Sie haben den Vergleich hier etwas falsch verstanden – die Funktion „Get Rows Where“ wertet den Ausdruck in jeder Zeile aus, daher müssen Sie alle überflüssigen Suchvorgänge minimieren, bevor Sie die Schleife ausführen – insbesondere ist Ihr Iterator extern und er Um es in jeder Zeile zu finden, muss man etwas herumlaufen.Außerdem wird die AsColumn-Funktion für jede Zeile ausgewertet und jedes Mal sowohl „dt“ als auch „i“ nachgeschlagen.Das ist _sehr_ teuer.Der richtige Weg dazu wäre wie folgt:
names default to here(1);
dt=current data table();
start=hptime();
names = dt << Get Column Names( "string" );
for(i=5,i<= ncols(dt),i++,
Eval( Parse( Eval InserT( JSL Quote(
column(dt,i)[dt<<GET rows="" where=""></GET>
Sie werden feststellen, dass dies in der Größenordnung von 3000x schneller ausgeführt wird, was es mit den anderen Methoden, die Sie haben, vergleichbar, wenn nicht sogar besser machen sollte
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Ja ... die Hürde besteht darin, dass auf Matrizen zwar mit einem einzigen Index zugegriffen werden kann (was ein zeilenorientiertes Layout voraussetzt), Datentabellen jedoch nicht. Daher gibt es leider kein Analogon dazu
m[loc(m, 9999)] = .
wobei m eine pxq-Matrix in der Datentabellenwelt ist ... daher die Zeilen vor und nach dieser im obigen Code. Obwohl der Code immer noch schnell ist, wäre er WIRKLICH schnell, wenn für Tabellen ein Einzelindexzugriff verfügbar wäre.
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Für die ' Mehraufwand bei der Erstellung einer Matrix', vermute ich Abonnieren der Datentabelle könnte helfen.@Craige_Hales würde wissen.
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Dies ist eine Möglichkeit, Schleifen zu vermeiden, auch wenn die Erstellung einer Matrix und die anschließende Zuweisung zurück zur Tabelle mit einem Mehraufwand verbunden sind. Dieser Ansatz ist bei diesen Daten schnell und ungefähr genauso schnell wie loc_2d, aber wenn die Tabelle riesig wird, erwarte ich, dass ihre relative Leistung leidet, aber ich habe dies nicht überprüft.
expr_mat = expr(
m = dt[0, 5 :: N Col( dt )];
m[Loc( m, 999 )] = .;
dt[0, 5 :: N Col( dt )] = m;
);
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Ich habe mich vielleicht etwas zu sehr damit beschäftigt (habe aber zumindest eine Vorstellung davon, wie ich diese Art von Tests später durchführen kann, wenn es sein muss).
Ich habe eine Art Testskript mit verschiedenen Ausdrücken geschrieben, um verschiedene Möglichkeiten zum Ersetzen der 999 durch fehlt zu testen. Ich habe mit zwei Datensätzen (Semiconductor Capability.jmp und Probe.jmp) getestet und die Anzahl der fehlenden Werte in den Spalten geändert.
Loc() ersetzt Werte am schnellsten (keine Überraschung). Missing Value Codes() ist „immer“ schnell, hat aber im Vergleich zu Loc() etwas eingeschränktere Anwendungsfälle und ist etwas umständlicher, wenn mehrere Werte ersetzt werden müssten.

Am schnellsten war am Ende loc_2d (ich habe mir nicht die Mühe gemacht, die Variablennamen von hier aus zu ändern: Verwenden von Loc mit einer 2D-Matrix ). Es muss immer noch eine Schleife durchgeführt werden, um Werte festzulegen (zumindest meines Wissens). Der Grund dafür, dass dies schneller als nur Loc() ist, liegt höchstwahrscheinlich darin, dass einige Spalten übersprungen werden. Unten sind expr_loc2d und expr_loc:
expr_loc = Expr(
for(i=5,i<= ncols(testData),i++,
column(testData,i)[Loc(testData[0,i], 999)]=.;
);
);
expr_loc_2d = Expr(
mat = testData[0,5::NCols(testData)];
nr = N Rows(mat);
nc = N Cols(mat);
blacklocs = Loc(mat, 999) - 1;
rowlocs = Floor((blacklocs) / nc ) + 1;
collocs = Mod((blacklocs), nc ) + 1 + 4;
uniqCols = Associative Array(collocs) << get keys;
For(i_2d = 1, i_2d <= N Items(uniqCols), i_2d++,
testData[rowlocs[Loc(collocs, uniqCols[i_2d])], uniqCols[i_2d]] = .;
);
);
Außerdem scheint es wichtig zu sein, AsColumn(Column(dt, i)) wie zu verwenden @Ryan_Gilmore sagte (ich habe mir nicht einmal die Mühe gemacht, << get rows where ohne zu testen, weil es sehr langsam sein wird), aber ich habe die Neucodierung mit und ohne Column() getestet. Außerdem ist mir gerade aufgefallen, dass ich bei der Neucodierung eine Column() übersehen habe, also führe ein paar Schnelltests durch (nicht in den Daten oder im Skript angehängt):
Ziemlich großer Unterschied zwischen diesen drei:
expr_recode_ascolumn = Expr(
For(i = 5, i <= N Cols(testData), i++,
testData << Recode Column(
As Column(dt, i),
{If( _rcNow == 999, ., _rcNow)},
Target Column(As Column(testData, i))
)
);
);
expr_recode_ascolumn_column = Expr(
For(i = 5, i <= N Cols(testData), i++,
testData << Recode Column(
As Column(dt, i),
{If( _rcNow == 999, ., _rcNow)},
Target Column(As Column(Column(testData, i)))
)
);
);<BR />
expr_recode_ascolumn_column_column = Expr(
For(i = 5, i <= N Cols(testData), i++,
testData << Recode Column(
As Column(Column(dt, i)),
{If( _rcNow == 999, ., _rcNow)},
Target Column(As Column(Column(testData, i)))
)
);
);

Das Testskript und einige Ergebnisdaten sind beigefügt. Das Skript wird höchstwahrscheinlich hier und da einige Fehler enthalten. Sollte es ziemlich einfach sein, neue Ausdrücke hinzuzufügen, wenn jemand dies möchte. Eine Sache, die ich überhaupt nicht getestet habe, ist die Verwendung von << Begin/End data update.
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Interessante Diskussion! Die Datentabellenmatrix-Notation, die meiner Meinung nach erstmals in JMP 13 erschien, ist für die Zuweisung recht effizient.
Für dieses spezielle Problem ist es fast 500-mal schneller als die for-Schleife (0,003 vs. 1,5 Sekunden, JMP 15 Mac-Laptop).
start = HP Time();
For( i = 5, i <= N Cols( dt ), i++,
Try( dt[Loc( dt[0, i], 999 ), i] = . )
);
Show( HP Time() - start);
Das try() wird benötigt, um einen Fehler für Spalten ohne „999“ zu vermeiden.
Eine Schleife über Spalten ist immer noch notwendig, da eine direkte Zuweisung für die gesamte Matrix, von der ich kurz dachte, dass sie noch schneller wäre, nicht funktioniert. Fehler: „Mehrere Indizes erfordern einzelne Indizes auf jeder inneren Ebene beim Zugriff oder bei der Auswertung …“, was bei näherer Betrachtung Sinn macht.
// The left Data Table matrix syntax is OK on its own, but not for assignment.
dt[0, 5 :: N Col( dt )][Loc( dt[0, 5 :: N Col( dt )], 999 )] = .;
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Irgendwann war ich vielleicht davor zurückgeschreckt, Schleifen zu verwenden, aber nachdem ich einen Algorithmus-Kurs besucht hatte (den ich nie abgeschlossen habe …), war das etwas weniger der Fall. Man muss nur effizient mit ihnen umgehen, da es oft zu viele Schleifen gibt (Zeitkomplexität und Big-O-Notation). Außerdem ist die Verwendung von Schleifen viel einfacher als der Versuch, Probleme mit reiner Mathematik zu lösen.
Bei JMP verwende ich normalerweise einfach die sicheren Optionen, die ich irgendwann gelernt habe, da die Geschwindigkeit selten ein Problem darstellt. Aber wenn die Zeit ein Problem ist (das Öffnen einer Anwendung dauerte bei der Arbeit mehr als 6 Minuten), werde ich nach Möglichkeiten suchen, es schneller zu machen (es ist mir gelungen, den Start in weniger als 2 Minuten zu ermöglichen). In diesem Fall ist es mir gelungen, es schneller zu machen, indem ich Loc() mit verschiedenen Kombinationen anderer Funktionen (Zeile löschen, Zeilenstatus festlegen) verwendet habe.
Zusätzlich zu Loc() scheint die Verwendung von Summarize() „viel“ schneller zu sein, verglichen mit meiner seit langem bevorzugten Option zum Abrufen eindeutiger Werte in Spalten (assoziatives Array() << Schlüssel abrufen). Wenn die Zeilenanzahl zunimmt, wird das Associative Array() << Get Keys immer langsamer und Summarize() scheint nicht unter demselben Problem zu leiden, zumindest nicht so schnell. Deshalb habe ich versucht, Summarize() häufiger zu verwenden (ich weiß nie, wie groß die Datentabellen werden).
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Also überspringen wir AsColumn() mit (wobei wir eher von einer Ahnung ausgehen und ich nicht getestet habe, dass dadurch alle korrekten Werte ersetzt werden):
start=hptime();
for(i=5,i<= ncols(dt),i++,
column(dt,i)[Loc(dt[0,i], 999)]=.;
if(mod(i,10)==0,show(i));
);
show(hptime()-start);
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Ich stimme zu, dass Loc() die beste Methode ist.
Für mich scheint die Verlangsamung auf As Column zurückzuführen zu sein. Ich sehe einen signifikanten Unterschied zwischen,
start = HP Time();
For( i = 5, i <= N Cols( dt ), i++,
As Column( column(dt, i) );
);
Show( HP Time() - start );
Und
start = HP Time();
For( i = 5, i <= N Cols( dt ), i++,
As Column( dt, i );
);
Show( HP Time() - start );
Ändern der As Column-Syntax im Code von @txnelson Ursprüngliche Frage: Die For-Schleife ist immer noch die schnellste, aber die anderen sind vergleichbarer.
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Hallo @txnelson ,
Sehr interessanter Vergleich und auch nicht die Ergebnisse, die ich erwartet hätte. Ich erinnere mich, als ich an der Uni anfing, Programmieren zu lernen, und mir wurde auch etwas Ähnliches beigebracht: Seien Sie vorsichtig bei Schleifen, weil sie langsam sind.
Sicherlich habe ich bei einigen Berechnungen und in einigen Programmen festgestellt, dass For-Schleifen sehr langsam sind – langsamer als die Alternativen. Da ich aber kein besonders guter Programmierer bin, neige ich dazu, auf das zurückzugreifen, was ich kann, was nicht immer schnell oder elegant ist. Manchmal ermöglicht es mir die Logik einer Schleife, einen funktionierenden Code zu schreiben, der das tut, was ich möchte, und so mit den nächsten Schritten fortzufahren.
Ich finde es interessant, dass die Optionen „For-Schleife“ und „Neu kodieren“ bei JMP 16 im Vergleich zu 15 etwas langsamer sind, aber „Zeilen abrufen“ wurde verbessert, indem die Zeit fast halbiert wurde, was eine wesentliche Änderung darstellt.
Danke!,
DS
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Vielleicht @Craige_Hales Könnte uns eine noch schnellere Lösung bieten. Die Idee, Matrixberechnungen (insbesondere Loc()) zu verwenden, kam mir aus seinen Community-Beiträgen/Blogs.
Ich habe ein Tool schneller gemacht, das Datensätze öffnet und dann alte Daten löscht (basierend auf der Benutzerauswahl). Ursprünglich wurde << „Wo auswählen“ und „Zeilen löschen“ verwendet. Ich habe es durch etwas Loc()-Magie ersetzt und es wurde auch viel schneller. Loc() hat mir in letzter Zeit sehr gut gefallen.
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?@jthi ,
Ihr Matrix-basierter Code war der schnellste.
0,299795 Sekunden.......
Betreff: Sollten Sie eine Datentabelle durchlaufen oder Recode verwenden oder Get Rows Where verwenden, um Werte in einer Datentabelle zu ändern?Ich habe bei der Arbeit einige Optimierungen an einigen alten Skripten vorgenommen, die wir haben. Einige der Dinge, die ich ändern musste, bezogen sich darauf, die Zeilen dorthin zu bringen, wo sie hingehören. Ich habe begonnen, immer mehr Matrixoperationen (hauptsächlich Loc()) zu verwenden, wenn ich schnellen JSL-Code benötige.
Sie könnten beispielsweise die Position der Get-Zeilen wie folgt ändern (es wurde nicht getestet, ob dadurch die richtigen Werte oder alle ersetzt werden):
start=hptime();
for(i=5,i<= ncols(dt),i++,
column(dt,i)[Loc(ascolumn(dt,i) << get as matrix, 999)]=.;
if(mod(i,10)==0,show(i));
);
show(hptime()-start);
Es besteht auch die Möglichkeit, die Spalteneigenschaften „Wertbeschriftungen“ und „Codes für fehlende Werte“ zu verwenden, was in manchen Fällen funktionieren kann. Ich verwende sie gerne, wenn möglich, da Sie dann die Daten nicht ändern.