Problem mit dem Skript zum Löschen redundanter Messungen, die für bestimmte Bedingungen spezifisch sindIch habe eine Datentabelle, die aus mehreren Reihen einzelner Messungen in Reihe besteht, die ich kürze, bevor ich eine Tabellenteilungsfunktion ausführe. Allerdings habe ich ein Problem mit einigen redundanten Messungen, die ich gerne entfernen würde, aber dem aktuellen Code I Ich verwende, ist extrem langsam und wahrscheinlich ineffizient für das, was ich brauche.
Hintergrundinformation:
- Jede Zeile ist das Ergebnis einer einzelnen automatisierten Messung an einem Materialstück, die in Serie durchgeführt wurde, und erstellt einen Bericht mit den folgenden Spalten:
- Eine eindeutige Teile-ID, die jedem einzelnen Materialstück zugewiesen ist [ PartID ]
- Die Chargen-ID, die dem Rohmaterial zugeordnet ist, das zur Herstellung des einzelnen Materialstücks verwendet wurde [LotID]
- Der tatsächliche Messwert für die durchgeführte Messung [Wert]
- Das auf der Grundlage des Messwerts zugewiesene Messergebnis (Bestanden/Nicht bestanden/Nacharbeit) [Ergebnis]
- Zeitstempel der Messung [Datum_Erstellung]
Meine Ausrüstung erzeugt Dutzende von Messwertreihen pro Materialstück und verarbeitet Tausende von Materialstücken pro Bericht – diese Berichte werden dann als meine ursprüngliche Datentabelle in JMP eingespeist.Jeder Bericht enthält auch mehrere Chargen, sodass die Datentabelle mehrere Verweise auf „PartID = 1“ enthält, da jede Charge eine fortlaufende Nummer erhält, die bei 1 beginnt. Daher muss ich sowohl PartID als auch LotID verwenden, um auf ein bestimmtes Materialstück zu verweisen.Wenn das Ergebnis „Nacharbeit“ lautet, stoppt das Messgerät alle weiteren Messungen an diesem einzelnen Materialstück, richtet das Materialstück neu aus und bringt es zum Anfang der Linie zurück, wobei alle vorherigen Tests erneut gemessen werden Material, behält aber immer noch die gleiche eindeutige Teile-ID bei, die mit dem Materialstück verknüpft war.
Gewünschtes Ergebnis:
Ich möchte ein Skript verwenden, um die Datentabelle durchzugehen und alle Messungen bis zum Nacharbeitsergebnis (einschließlich) zu eliminieren, da nach der Nacharbeit alle Messungen wiederholt werden und sich Nacharbeiten auf die Messwerte auswirken können.Dazu verwende ich derzeit ein JSL-Skript, um jede Zeile zu durchlaufen und Folgendes zu tun:
- Identifizieren Sie, ob das Ergebnis „Nacharbeit“ ist. Wenn ja, gehen Sie wie folgt vor:
- Identifizieren Sie die PartID für das angegebene Materialstück als „xPartID“.
- Identifizieren Sie die LotID für das angegebene Materialstück als „xLot“.
- Identifizieren Sie das Erstellungsdatum für die angegebene Messung als „xDate“.
- Wählen Sie alle Zeilen aus und löschen Sie sie, in denen (PartID = xPartID) und (LotID = xLot) und (Date_Created <= xDate)
- Wenn das Ergebnis nicht „Nacharbeit“ ist, verlassen Sie die Schleife und müssen nicht fortfahren.
Ich habe immer wieder extreme Verlangsamungen und im Grunde führt der Code dazu, dass das Programm abstürzt.Wenn ich es Schritt für Schritt ausführe, scheint es zu funktionieren, aber wenn ich es laufen lasse, stirbt es irgendwann ab. Hier ist der eigentliche Code:
//Recoding the two potential "Rework" results into a shared value "aRework"; putting the letter "a" in front of it so if I sort by the column ascending then all of these values are at the start of the list, to hopefully make it easier and faster to process them.
dt << Recode Column(
dt:result,
{Map Value(
_rcOrig,
{"FailOnHighRework", "aRework",
"FailOnLowRework", "aRework"},
Unmatched( _rcNow )
)},
Update Properties( 1 ),
Target Column( :result )
);
//Sorting the table using the result column after the recode, so all of the rework rows are at the start of the table
SortColumn = "result";
dt << Sort( By( :result ), Replace Table, Order( Ascending ), Suppress formula evaluation( 1 ) );
//now run the row-by-row script
dt << begin data update;
for each row(
If( :result == "aRework",
xRow = Row();
xPartID=:PartID[Row()];
xLot=:lot[Row()];
xDate=:date_created[Row()];
dt <<SELECT where=""></SELECT>Ich verwende JMP 16.2.0 (570548).
MassenanpassungBetreff: Problem mit dem Skript zum Löschen redundanter Messungen, die für bestimmte Bedingungen spezifisch sindHier ist eine Version des Skripts, das nach jeweils 100 verarbeiteten Zeilen in dt ausgedruckt wird
dt = Current Data Table();
dt << select where( :result == "aRework" );
dt2 = dt << subset( selected rows( 1 ), selected columns( 0 ) );
// Remove aRework rows from original table
dt << delete rows;
// Loop across the aRework table and delete rows in orininal table
//dt << begin data update;
start = 1;
end = 0;
alldt2 = N Rows( dt2 );
While( N Rows( dt2 ) > 100,
TotalRows = N Rows( dt2 );
If( TotalRows > 100,
TotalRows = 100
);
end = end + TotalRows;
For( i = 1, i <= TotalRows, i += 1,
dt << select where(
dt:partid == dt2:PartID[i] & dt:lot == dt2:Lot[i] & dt:date_created <= dt2
:Date_created[i]
);
If( N Rows( dt << get selected rows ) > 0,
dt << delete rows
);
);
//dt << end data update;
dt2 << delete rows( 1 :: 100 );
Show(
"Rows " || Char( start ) || " to " || Char( end ) || " of " || Char( alldt2 ) ||
" processed"
);
);
Close( dt2, nosave );
Sie können es auch so einrichten, dass nur x Zeilen verarbeitet werden, und es dann erneut ausführen, um weitere Zeilen zu verarbeiten.
Betreff: Problem mit dem Skript zum Löschen redundanter Messungen, die für bestimmte Bedingungen spezifisch sindHallo,
Das Skript scheint wie vorgesehen zu funktionieren, und wenn es mit einem sehr kleinen Datensatz (insgesamt 10.000 Zeilen) ausgeführt wird, scheint es gut und schnell zu sein, allerdings habe ich erhebliche Verlangsamungen mit dem tatsächlichen Datensatz, mit dem ich arbeite (1,6 Millionen Zeilen). ), so dass ich nicht sagen kann, ob es das Programm beendet (reagiert nicht, ließ es etwa 1,5 Stunden lang laufen und es schien immer noch zu laufen, aber der Prozess reagierte nicht und musste es schließlich über den Task-Manager „Task beenden“) - Irgendwelche Ratschläge zur Verbesserung?Das Ausführen gegen 10.000 Zeilen dauerte vielleicht < 10 Sekunden, also würde ich hoffen, dass es für 1,6 Millionen vielleicht 30 Minuten dauern würde, wenn es linear skaliert würde, aber das scheint nicht der Fall zu sein.
Ich lade eine bereinigte Teilmenge der Datentabelle als Referenz hoch, wobei die vorgeschlagene Skriptverbesserung in der Datentabelle gespeichert wird.In der bereinigten Tabelle war nur eine einzige LotID vorhanden. Dies ist jedoch normalerweise nicht der Fall und dient lediglich dazu, die Gesamtgröße der hochzuladenden Datei zu minimieren.
Hier ist die aktuelle Version des Skripts, das ich für die Tabelle ausführen möchte:
dt = current data table();
dt << select where( :result == "aRework" );
dt2 = dt << subset( selected rows( 1 ), selected columns( 0 ) );
// Remove aRework rows from original table
dt << delete rows;
// Loop across the aRework table and delete rows in orininal table
dt << begin data update;
TotalRows=N Rows(dt2);
For( i = 1, i <= N Rows( dt2 ), i+=1,
dt << select where(dt:partid == dt2:PartID[i] & dt:lot == dt2:Lot[i] & dt:date_created <= dt2:Date_created[i]);
If( N Rows( dt << get selected rows ) > 0,
dt << delete rows
);
);
dt << end data update;
close( dt2, nosave );
Nochmals vielen Dank für die Hilfe!
Betreff: Problem mit dem Skript zum Löschen redundanter Messungen, die für bestimmte Bedingungen spezifisch sindHallo und dankeschön!
Ich führe das Skript jetzt für meine Datentabelle aus; Ich denke, Sie hatten definitiv Recht, als ich die Zeilen einer Tabelle durchgegangen bin, bei der die Zeile, die als gelöscht betrachtet wird, aktiv ist, was wahrscheinlich die Schleifenlogik durcheinander gebracht hat.
Ich führe den Code jetzt gegen meine Datentabelle aus und werde darüber berichten.Ich werde auch versuchen, einen Ausschnitt meiner Datentabelle zu bereinigen, damit ich ihn in diesen Beitrag einfügen kann.Vielen Dank für Ihre Hilfe!
Betreff: Problem mit dem Skript zum Löschen redundanter Messungen, die für bestimmte Bedingungen spezifisch sindIch glaube, Sie stoßen auf ein Problem, bei dem Sie eine Datentabelle mit „Für jede Zeile“ durchlaufen und die Tabelle, die Sie durchlaufen, ständig ändern, indem Sie Zeilen löschen, und die Schleife wird verwirrt.
Hier ist ein ungetesteter Code, der meiner Meinung nach das Problem beheben wird und ziemlich effizient laufen sollte.
Names Default To Here( 1 );
//Recoding the two potential "Rework" results into a shared value "aRework"; putting the letter "a" in front of it so if I sort by the column ascending then all of these values are at the start of the list, to hopefully make it easier and faster to process them.
dt << Recode Column(
dt:result,
{Map Value( _rcOrig, {"FailOnHighRework", "aRework", "FailOnLowRework", "aRework"}, Unmatched( _rcNow ) )},
Update Properties( 1 ),
Target Column( :result )
);
dt << select where( :result == "aRework" );
dt2 = dt << subset( selected rows( 1 ), selected columns( 0 ) );
// Remove aRework rows from original table
dt << delete rows;
// Loop across the aRework table and delete rows in orininal table
For( i = 1, i <= N Rows( dt2 ), i++,
dt << select where(
(dt:partid == dt2:PartID[i] & dt:lot == dt2:Lot[i] & dt:date_created <= dt2:Date_created[i]);
If( N Rows( dt << get selected ) > 0,
dt << delete rows
);
)
);
close( dt2, nosave );
Ich hatte keine Beispieldatentabelle, mit der ich arbeiten konnte, daher ist der Code ungetestet, aber der Ansatz sollte es Ihnen ermöglichen, alle Probleme zu beheben und ihn zum Laufen zu bringen.